WPF样式中的DataTrigger绑定

15

在WPF中我有以下按钮和样式,我需要将DataTrigger部分的绑定泛化,因为在同一个窗口中我有近10个相似的按钮,且每个按钮都应该绑定到不同的属性(SelectedPositions, SelectedAgencies,.....)。这个可行吗?

    <Button x:Name="btnPosition"
            Grid.Row="0"
            Grid.Column="0"
            HorizontalAlignment="Left"
            VerticalAlignment="Center"
            Command="{Binding PositionFilterCommand}"
            Content="{l:Translate position}"
            Style="{StaticResource NewButtonStyle}" />

    <Style x:Key="NewButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Height" Value="22" />
        <Setter Property="Width" Value="Auto" />
        <Setter Property="FontFamily" Value="OpenSans" />
        <Setter Property="FontSize" Value="13" />
        <Setter Property="Cursor" Value="Hand" />
        <Setter Property="Margin" Value="10,2,10,0" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border CornerRadius="3">
                        <Grid x:Name="gridButton" Background="#54728e">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Image x:Name="img"
                                   Grid.Column="0"
                                   Width="24"
                                   Height="24"
                                   Source="Img/tick-white.png"
                                   Visibility="Visible" />
                            <Rectangle x:Name="rect"
                                       Grid.Column="1"
                                       Fill="#54728e"
                                       RadiusX="3"
                                       RadiusY="3" />
                            <ContentPresenter Grid.Column="1"
                                              Margin="5,0,5,0"
                                              HorizontalAlignment="Stretch"
                                              VerticalAlignment="Center" />
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding SelectedPositions}" Value="{x:Static sys:String.Empty}">
                            <Setter TargetName="rect" Property="Fill" Value="#8bbcdf" />
                            <Setter TargetName="img" Property="Visibility" Value="Collapsed" />
                            <Setter TargetName="gridButton" Property="Background" Value="#8bbcdf" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

这些属性(SelectedPositions,SelectedAgencies,...)是否都是相同类型的?如果是,则可以将附加属性或普通依赖属性绑定到按钮,并在公共样式中检查该值,在控件上将此DP绑定到每个相应的源属性。您还可以使用“Tag”属性来完成相同的操作,尽管这通常是被不赞成的做法。 - Viv
1
是的,这些属性都是相同类型(字符串)。每个按钮都有自己的属性、内容和命令。请问您能否给我一个您所解释的例子?非常感谢。 - MauroBahia
好的,每个都添加了一个示例。您可以选择其中一个,并进一步了解哪个最适合您的要求。 - Viv
1个回答

36
你能给我一个你解释的例子吗?
当然,
1 - 使用标签
在你的样式中,将你的DataTrigger设置为:
<DataTrigger Binding="{Binding Path=Tag,
                                RelativeSource={RelativeSource Self}}"
              Value="{x:Static sys:String.Empty}">
  ...
</DataTrigger>

关于用法:
<Button x:Name="btnPosition"
            Grid.Row="0"
            Grid.Column="0"
            HorizontalAlignment="Left"
            VerticalAlignment="Center"
            Command="{Binding PositionFilterCommand}"
            Content="{l:Translate position}"
            Tag="{Binding SelectedPositions}"
            Style="{StaticResource NewButtonStyle}" />

2 - 使用“附加属性”:

“local:” 是您应用程序的 XAML 命名空间别名,或者如果您使用不同的命名空间,则是声明 MyCustomPropertyCollection 的命名空间。

代码后台:

public class MyCustomPropertyCollection {
  public static readonly DependencyProperty SomeStringProperty =
    DependencyProperty.RegisterAttached(
      "SomeString",
      typeof(string),
      typeof(MyCustomPropertyCollection),
      new FrameworkPropertyMetadata(string.Empty));

  public static void SetSomeString(UIElement element, string value) {
    element.SetValue(SomeStringProperty, value);
  }

  public static string GetSomeString(UIElement element) {
    return (string)element.GetValue(SomeStringProperty);
  }
}

Style.DataTrigger

<DataTrigger Binding="{Binding Path=(local:MyCustomPropertyCollection.SomeString),
                                RelativeSource={RelativeSource Self}}"
              Value="{x:Static sys:String.Empty}">
  ...
</DataTrigger>

用法:
<Button x:Name="btnPosition"
            Grid.Row="0"
            Grid.Column="0"
            HorizontalAlignment="Left"
            VerticalAlignment="Center"
            Command="{Binding PositionFilterCommand}"
            Content="{l:Translate position}"
            local:MyCustomPropertyCollection.SomeString="{Binding SelectedPositions}"
            Style="{StaticResource NewButtonStyle}" />

3 - 普通依赖属性
自定义Button类:
public class MyButton : Button {
  public static readonly DependencyProperty SomeStringProperty =
    DependencyProperty.Register(
      "SomeString",
      typeof(string),
      typeof(MyButton),
      new FrameworkPropertyMetadata(string.Empty));

  public string SomeString {
    get {
      return (string)GetValue(SomeStringProperty);
    }
    set {
      SetValue(SomeStringProperty, value);
    }
  }
}

在 XAML 中,样式不仅需要更新 DataTrigger,还需要更新样式定义。因此,请切换。
<Style x:Key="NewButtonStyle" TargetType="{x:Type Button}">

to

<Style x:Key="NewButtonStyle" TargetType="{x:Type local:MyButton}">

Style.DataTrigger

<DataTrigger Binding="{Binding Path=SomeString,
                                RelativeSource={RelativeSource Self}}"
              Value="{x:Static sys:String.Empty}">
  ...
</DataTrigger>

用法:
<local:MyButton x:Name="btnPosition"
            Grid.Row="0"
            Grid.Column="0"
            HorizontalAlignment="Left"
            VerticalAlignment="Center"
            Command="{Binding PositionFilterCommand}"
            Content="{l:Translate position}"
            SomeString="{Binding SelectedPositions}"
            Style="{StaticResource NewButtonStyle}" />

“标签”方法不被推荐使用。使用“附加属性”更容易实现,但不能像带有普通 DP 的自定义类那样清晰地指示依赖项,而且 AP 被过度使用。你可以选择自己喜欢的方式。

如果我想要触发一个特定字符串而不是String.Empty,那么Value="..."会是什么样子? - phonetagger
如果可以的话,您能否看一下我的当前问题,并告诉我如何基于枚举执行DataTrigger?http://stackoverflow.com/q/31615946/1245420 - phonetagger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接