как динамически изменить шаблон кнопки WPF - PullRequest
0 голосов
/ 05 октября 2010

Как я могу динамически изменить шаблон Button?

У меня есть ComboBox, где, изменяя его выбранное значение, я хочу изменить Button Template. Вот что я пытался сделать:

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

А вот соответствующие Template s:

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

И код позади:

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

Есть ли другой родовой способ сделать это? ... Я хочу, чтобы большая часть кода была бы xaml.

EDIT:

Есть ли смысл делать это, используя стиль? Допустим, я хочу, чтобы действовал более одного объекта, иначе есть ли смысл изменить стиль и сделать все это оттуда?

Ответы [ 3 ]

2 голосов
/ 05 октября 2010
    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;
            }
        } 
    }
1 голос
/ 05 октября 2010

Вы можете использовать триггер данных и делать все это в xaml.

Используется дерево, но концепция та же

<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">

из здесь .

(я просто погуглил, чтобы получить пример быстрее)

0 голосов
/ 18 мая 2015

Создать шаблон ControlTemplate в Windows,

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

Теперь во время выполнения вы можете изменить свойство шаблона кнопки.

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