【问题标题】:Binding Data to Button Style with DataTrigger使用 DataTrigger 将数据绑定到按钮样式
【发布时间】:2021-03-11 12:18:49
【问题描述】:

我正在使用 WPF 构建一个菜单,但我想简化创建新样式的代码。 目前,菜单运行良好:

<Button Name="btnMenu1" Grid.Row="0" Content="Button One" Click="BtnMenu1_Click">
    <Button.Style>
        <Style TargetType="Button">
            <Style.Triggers>
                <DataTrigger Binding="{Binding [0].Selected}" Value="True">
                    <Setter Property="Foreground" Value="Yellow" />
                </DataTrigger>
                <DataTrigger Binding="{Binding [0].Selected}" Value="False">
                    <Setter Property="Foreground" Value="Blue" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>
<Button Name="btnMenu2" Grid.Row="1" Content="Button Two" Click="BtnMenu2_Click">
    <Button.Style>
        <Style TargetType="Button">
            <Style.Triggers>
                <DataTrigger Binding="{Binding [1].Selected}" Value="True">
                    <Setter Property="Foreground" Value="Yellow" />
                </DataTrigger>
                <DataTrigger Binding="{Binding [1].Selected}" Value="False">
                    <Setter Property="Foreground" Value="Blue" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

想象一下我需要在菜单中添加 10 或 15 个按钮,你能想象代码的数量吗? 我的想法是简化代码:

<Button Name="btnMenu1" Grid.Row="0" Style="{StaticResource StyleButtonMenu}" Content="Button One" Click="BtnMenu1_Click"/>
<Button Name="btnMenu2" Grid.Row="1" Style="{StaticResource StyleButtonMenu}" Content="Button Two" Click="BtnMenu2_Click"/>
<Button Name="btnMenu3" Grid.Row="2" Style="{StaticResource StyleButtonMenu}" Content="Button Three" Click="BtnMenu3_Click"/>
<Button Name="btnMenu4" Grid.Row="3" Style="{StaticResource StyleButtonMenu}" Content="Button Four" Click="BtnMenu4_Click"/>
<Button Name="btnMenu5" Grid.Row="4" Style="{StaticResource StyleButtonMenu}" Content="Button Five" Click="BtnMenu5_Click"/>

代码风格可能是这样的:

<Style x:Key="StyleButtonMenu" TargetType="Button">
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="Cursor" Value="Hand" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Selected}" Value="True">
            <Setter Property="Foreground" Value="Yellow"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Selected}" Value="False">
            <Setter Property="Foreground" Value="Blue"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

我的问题是:我如何与DataTrigger 中的Bindings 一起处理属性Selected? 我有一个带有属性的List,当某些属性发生变化时,我需要更新 UI。 正如我在顶部所说,代码效果很好,我只想创建一个通用样式并处理 DataTrigger 中的绑定。

【问题讨论】:

  • “菜单上有 10 或 15 个按钮,你能想象代码的数量吗” - 很少:一个 ItemsControl(例如 64 buttons
  • 我会看看并尝试理解

标签: c# .net wpf xaml


【解决方案1】:

对于您的静态示例,您可以使用 DataTrigger 以您的样式绑定 Tag

<Style x:Key="StyleButtonMenu" TargetType="Button">
   <Setter Property="BorderThickness" Value="0" />
   <Setter Property="Cursor" Value="Hand" />
   <Setter Property="Foreground" Value="Blue"/>
   <Style.Triggers>
      <DataTrigger Binding="{Binding Tag.Selected, RelativeSource={RelativeSource Self}}" Value="True">
         <Setter Property="Foreground" Value="Yellow"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

然后,您可以将具体数据上下文绑定到每个按钮的Tag

<Button Name="btnMenu1" Grid.Row="0" Tag="{Binding [0]}" Style="{StaticResource StyleButtonMenu}" Content="Button One" Click="BtnMenu1_Click"/>
<Button Name="btnMenu2" Grid.Row="1" Tag="{Binding [1]}" Style="{StaticResource StyleButtonMenu}" Content="Button Two" Click="BtnMenu2_Click"/>
<Button Name="btnMenu3" Grid.Row="2" Tag="{Binding [2]}" Style="{StaticResource StyleButtonMenu}" Content="Button Three" Click="BtnMenu3_Click"/>
<Button Name="btnMenu4" Grid.Row="3" Tag="{Binding [3]}" Style="{StaticResource StyleButtonMenu}" Content="Button Four" Click="BtnMenu4_Click"/>
<Button Name="btnMenu5" Grid.Row="4" Tag="{Binding [4]}" Style="{StaticResource StyleButtonMenu}" Content="Button Five" Click="BtnMenu5_Click"/>

但是,还有更好的方法。每当您尝试显示数据项的集合时,请考虑使用 ItemsControl 或任何适合您的用例的派生类型。在这里,您可以将 ItemsControl 与数据模板一起使用,因为您不需要选择或任何特殊的东西。

<Style x:Key="MenuButtonStyle" TargetType="Button">
   <Setter Property="BorderThickness" Value="0" />
   <Setter Property="Cursor" Value="Hand" />
   <Setter Property="Foreground" Value="Blue"/>
   <Style.Triggers>
      <DataTrigger Binding="{Binding Selected}" Value="True">
         <Setter Property="Foreground" Value="Yellow"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

<DataTemplate x:Key="MenuItemTemplate">
   <Button Style="{StaticResource MenuButtonStyle}"
           Content="{Binding Name}"
           Command="{Binding DoSomething}"
           CommandParameter="{Binding}">
   </Button>
</DataTemplate>

此数据模板假定您的菜单项数据类型包含问题中的NameDoSomethingSelected 属性。根据您的要求,DoSomething 命令也可能在父数据上下文中定义。此命令将处理按钮单击。

您现在可以将项目集合(此处为 MenuItems)绑定到具有上述数据模板的 ItemsControl,而不是带有硬编码按钮的 Grid

<ItemsControl ItemsSource="{Binding MenuItems}"
              ItemTemplate="{StaticResource MenuItemTemplate}"/>

【讨论】:

  • 感谢您的帮助。现在我将使用 Tag 方法。以后我会探索ItemsControl
猜你喜欢
  • 2017-01-23
  • 1970-01-01
  • 2013-07-10
  • 2017-08-22
  • 2013-10-19
  • 2012-01-09
  • 2011-10-09
  • 2014-06-05
  • 2017-08-09
相关资源
最近更新 更多