开发者

how to change button template dynamically WPF

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" M开发者_StackOverflow中文版argin="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?


    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;
            }
        } 
    }


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;
        }
    }


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">
        <TextBlock Name="textBlock" Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
</Window.Resources>
<StackPanel>
<TreeView ItemTemplate="{StaticResource template}"
          Name="treeView"
          ItemsSource="{Binding Source={StaticResource treeData}}">
    <TreeView.ItemContainerStyle>
        <!--Using style setter to set the TreeViewItem.IsExpanded property to true, this will be applied
  to all TreeViweItems when they are generated-->
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="True"/>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>
    <Button Width="120" Height="30">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="Content" Value="Default" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=treeView, Path=SelectedItem.Name}" Value="Item12">
                        <Setter  Property="Content" Value="Now changed" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

from here.

(I just googled to get an example faster)

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜