开发者

Content doesn't show on ToggleButton styled and templated in code

I found myself needing to define some styles and templates for a couple ToggleButton elements that I'm using in one of my programs. I have everything working, except that whatever I set as the content on them doesn't show. I'm at a loss as to how to get my contents to display correctly. My code is as follows:

    private Style m_ToggleStyle;
    private Style ToggleStyle
    {
        get
        {
            if (m_ToggleStyle == null)
            {
                lock (new object())
                {
                    if (m_ToggleStyle == null)
                    {
                        m_ToggleStyle = new Style(typeof(ToggleButton));

                        m_ToggleStyle.Setters.Add(new Setter { Property = ToggleButton.TemplateProperty, Value = ToggleTemplate });
                    }
                }
            }
            return m_ToggleStyle;
        }
    }

    private ControlTemplate m_ToggleTemplate;
    private ControlTemplate ToggleTemplate
    {
        get
        {
            if (m_ToggleTemplate == null)
            {
                lock (new object())
                {
                    if (m_ToggleTemplate == null)
                    {
                        m_ToggleTemplate = new ControlTemplate();
                        FrameworkElementFactory g = new开发者_StackOverflow FrameworkElementFactory(typeof(Grid));
                        g.SetValue(Grid.MarginProperty, new Thickness(0));
                        g.Name = "MainGrid";

                        FrameworkElementFactory cp = new FrameworkElementFactory(typeof(ContentPresenter));
                        cp.SetValue(ContentPresenter.NameProperty, "Contents");
                        cp.SetValue(ContentPresenter.HorizontalAlignmentProperty, System.Windows.HorizontalAlignment.Stretch);
                        cp.SetValue(ContentPresenter.VerticalAlignmentProperty, System.Windows.VerticalAlignment.Stretch);
                        cp.SetValue(ContentPresenter.MarginProperty, new Thickness(2));
                        cp.Name = "Contents";

                        g.AppendChild(cp);
                        m_ToggleTemplate.VisualTree = g;

                        ImageBrush ibBackgroundUnselected = new ImageBrush();
                        ibBackgroundUnselected.ImageSource = new BitmapImage(new Uri("pack://application:,,,/Controls;component/Resources/TabUnselected.png", UriKind.Absolute));
                        g.SetValue(Grid.BackgroundProperty, ibBackgroundUnselected);

                        ImageBrush ibBackgroundSelected = new ImageBrush();
                        ibBackgroundSelected.ImageSource = new BitmapImage(new Uri("pack://application:,,,/Controls;component/Resources/TabSelected.png", UriKind.Absolute));

                        Trigger tIsChecked = new Trigger { Property = ToggleButton.IsCheckedProperty, Value = true };
                        tIsChecked.Setters.Add(new Setter(Grid.BackgroundProperty, ibBackgroundSelected, "MainGrid"));

                        m_ToggleTemplate.Triggers.Add(tIsChecked);

                    }
                }
            }
            return m_ToggleTemplate;
        }
    }

This is used as I dynamically create ToggleButtons like:

ToggleButton tbExample = new ToggleButton();
tbExample.Style = ToggleStyle;
tbExample.Content = "Content";


I'm not seeing the line where you assign the VisualTree of m_ToggleTemplate. You have this line:

m_LocationSelectionTemplate.VisualTree = g;

But nowhere in your ToggleTemplate accessor do you actually set a valid value for m_ToggleTemplate.

Something else to note is your use of FrameworkElementFactory. According to MSDN, this is not the best way to create control templates, and is in fact deprecated:

This class is a deprecated way to programmatically create templates, which are subclasses of FrameworkTemplate such as ControlTemplate or DataTemplate; not all of the template functionality is available when you create a template using this class. The recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Load method of the XamlReader class.


FrameworkElementFactory cp = new FrameworkElementFactory(typeof(ContentPresenter));
cp.SetValue(ContentPresenter.NameProperty, "Contents");

// try adding this line
cp.SetValue(ContentPresenter.ContentSourceProperty, "Content");


Found the problem:

m_ToggleTemplate = new ControlTemplate();

Should have been:

m_ToggleTemplate = new ControlTemplate(typeof(ToggleButton));

Apparently if you don't set the type of the ControlTemplate, it only partially works.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜