【问题标题】:how to change button template dynamically WPF如何动态更改按钮模板WPF
【发布时间】:2010-10-05 12:56:53
【问题描述】:

如何动态更改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>

这里是关联的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>

以及背后的代码:

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。

编辑:

使用样式是否有意义?假设我想要不止一个对象来行动,否则是否有必要改变风格并从那里完成所有工作?

【问题讨论】:

    标签: wpf button binding controltemplate


    【解决方案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;
                }
            } 
        }
    

    【讨论】:

    • 我似乎有一个问题,我将 FindResource 放在虚拟机中,我没有 hom 可以请你帮忙吗?
    • 控件模板和其他资源属于视图,如果跟随 MVVM,您的 VM 不应引用您的视图。我会将键存储在 VM(“ButtonControlTemplate1”、“ButtonControlTemplate2”)中,并使用视图类中的一些代码将键映射到使用 FindResource 的 ControlTemplatwe。如果要将 ControlTemplate 存储在 VM 中,则可以使用后面的代码在 VM 中创建它们,或者让视图在其 Loaded 处理程序中填充 VM 中的 ControlTemplate 集合。
    【解决方案2】:

    在 Windows 资源中创建一个 ControlTemplate,

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

    【讨论】:

      【解决方案3】:

      您可以使用数据触发器并在 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">
              <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>
      

      来自here

      (我只是用谷歌搜索了一个更快的例子)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-19
        • 2015-02-22
        • 2019-04-05
        • 1970-01-01
        相关资源
        最近更新 更多