how to change button template dynamically WPF

*爱你&永不变心* 提交于 2020-01-11 04:20:08

问题


How can I change a Button template dynamically?

I have a ComboBox where by changing his selected value I want to change a Button Template. This is what I have been trying to do:

<Window.Resources>
    <ControlTemplate x:Key="ButtonControlTemplate1" TargetType="{x:Type Button}">
        <Grid>
            <Rectangle Fill="#FF2D2D7A" Margin="7.5,9.5,8.5,11" Stroke="Black"
                       RadiusX="45" RadiusY="45" StrokeThickness="6"/>
        </Grid>
    </ControlTemplate>
    <ControlTemplate x:Key="ButtonControlTemplate2" TargetType="{x:Type Button}">
        <Grid>
            <ed:RegularPolygon Fill="#FFE7F9C9" Height="Auto" InnerRadius="0.47211"
                               Margin="20.5,16,15.5,8" PointCount="5" Stretch="Fill"
                               Stroke="Black" StrokeThickness="6" Width="Auto"/>
        </Grid>
    </ControlTemplate>
</Window.Resources>

<Grid x:Name="LayoutRoot">
    <ComboBox Name="GroupBoxHeaderComboBox" ItemsSource="{Binding Path=collection}" 
              DisplayMemberPath="Key" Height="52" Margin="211.5,60,230.5,0"
              VerticalAlignment="Top" SelectedIndex="1"/>
    <Button Content="Button" HorizontalAlignment="Left" Height="102" Margin="47.5,0,0,91"
            VerticalAlignment="Bottom" Width="132"
            Template="{DynamicResource ButtonControlTemplate2}"/>
    <Button Content="Button" HorizontalAlignment="Right" Height="112.5" Margin="0,0,27.5,85"
            VerticalAlignment="Bottom" Width="153"
            Template="{DynamicResource ButtonControlTemplate1}"/>
    <Button Content="Button" Height="102" Margin="239.5,0,252.5,13.5"
            VerticalAlignment="Bottom"
            Template="{Binding ElementName=GroupBoxHeaderComboBox, Path=SelectedItem.Value}"/>
</Grid>

And here are the associated Templates:

<Window.Resources>
    <ControlTemplate x:Key="ButtonControlTemplate1" TargetType="{x:Type Button}">
        <Grid>
            <Rectangle Fill="#FF2D2D7A" Margin="7.5,9.5,8.5,11" Stroke="Black"
                       RadiusX="45" RadiusY="45" StrokeThickness="6"/>
        </Grid>
    </ControlTemplate>
    <ControlTemplate x:Key="ButtonControlTemplate2" TargetType="{x:Type Button}">
        <Grid>
            <ed:RegularPolygon Fill="#FFE7F9C9" Height="Auto" InnerRadius="0.47211"
                               Margin="20.5,16,15.5,8" PointCount="5" Stretch="Fill"
                               Stroke="Black" StrokeThickness="6" Width="Auto"/>
        </Grid>
    </ControlTemplate>
</Window.Resources>

And the code behind:

public partial class MainWindow : Window
{
    public Dictionary<string, string> collection
    {
        get;
        private set;
    }

    public MainWindow()
    {
        this.InitializeComponent();
        DataContext = this;
        collection = new Dictionary<string, string>() 
        {
            { "DynamicResource ButtonControlTemplate2", "{DynamicResource ButtonControlTemplate2}"},
            { "DynamicResource ButtonControlTemplate1", "{DynamicResource ButtonControlTemplate2}"},

        };
    // Insert code required on object creation below this point.
    }
}

Is there another genric way to acomplish this?... I want that most of the code would be xaml.

EDIT:

Is there a point to do it using a style? Let's say I want more then one object to act, otherwise is there a point to change the style and to do it all from there?


回答1:


    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = this;
        }

        public Dictionary<string, ControlTemplate> collection
        {
            get
            {
                Dictionary<string, ControlTemplate> controlTemplates = new Dictionary<string, ControlTemplate>();
                controlTemplates.Add("ButtonControlTemplate1", FindResource("ButtonControlTemplate1") as ControlTemplate);
                controlTemplates.Add("ButtonControlTemplate2", FindResource("ButtonControlTemplate2") as ControlTemplate);
                return controlTemplates;
            }
        } 
    }



回答2:


You can use a data trigger and do it all in xaml.

This uses a tree but the concept is the same

<Window x:Class="WpfBindingTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfBindingTest"
Title="Window3" Height="300" Width="300"  Name="win3" >
<Window.Resources>
    <XmlDataProvider x:Key="treeData" XPath="*">
        <x:XData>
            <Items Name="Items" xmlns="">
                <Item1/>
                <Item2>
                    <Item22/>
                    <Item12/>
                    <Item13>
                        <Item131/>
                        <Item131/>
                    </Item13>
                </Item2>
            </Items>
        </x:XData>
    </XmlDataProvider>
    <HierarchicalDataTemplate ItemsSource="{Binding XPath=child::*}"

x:Key="template">

from here.

(I just googled to get an example faster)




回答3:


Create a ControlTemplate in Windows resource,

<Window.Resources>
    <ControlTemplate x:Key="GreenTemplate" TargetType="{x:Type Button}">
        <Grid>
            <Ellipse Fill="Green"/>
            <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
    </ControlTemplate>
</Window.Resources>

Now in run time you can change the template property of button.

    private void Button_Clicked(object sender, RoutedEventArgs e)
    {
        Button btn = e.OriginalSource as Button;
        if (btn != null)
        {
            btn.Template = FindResource("GreenTemplate") as ControlTemplate;
        }
    }


来源:https://stackoverflow.com/questions/3863799/how-to-change-button-template-dynamically-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!