c# - WPF 可重用 Style.Triggers

标签 c# wpf mvvm

我如何重用以下触发器?我需要将它重用于窗口中的所有清除按钮。按钮仅在 ListView 中选择项目时可见。所以我需要通过Binding ElementName=teachers作为参数。有没有办法做到这一点?

<Button Width="15"  Grid.Column="1" Content="X" Margin="0,2,5,2" Command="{Binding ClearSubjectCommand}" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Visibility" Value="Visible"></Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=teachers, Path=SelectedItem}" Value="{x:Null}">
                    <Setter Property="Visibility" Value="Collapsed"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

编辑

尝试了附加属性。但没有成功。
<Button Width="15"  Grid.Column="1" Content="X" Margin="0,2,5,2" Command="{Binding ClearSubjectCommand}"
        HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
        local:ThemeProperties.BindingElementName="teachers" Style="{StaticResource cancelButton}"/> 

和风格,
<Style TargetType="{x:Type Button}" x:Key="cancelButton">
    <Setter Property="Visibility" Value="Visible"></Setter>
    <Style.Triggers>
        <DataTrigger Binding="{Binding  ElementName= local:ThemeProperties.BindingElementName, Path=SelectedItem}" Value="{x:Null}">
            <Setter Property="Visibility" Value="Collapsed"></Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

类(class),
public static class ThemeProperties
{
    public static string GetBindingElementName(DependencyObject obj)
    {
        return (string)obj.GetValue(BindingElementNameProperty);
    }

    public static void SetBindingElementName(DependencyObject obj, string value)
    {
        obj.SetValue(BindingElementNameProperty, value);
    }

    // Using a DependencyProperty as the backing store for BindingElementName.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BindingElementNameProperty =
        DependencyProperty.RegisterAttached("BindingElementName", typeof(string), typeof(ThemeProperties), new FrameworkPropertyMetadata("teachers"));
}

最佳答案

将样式声明为 Resource 怎么样?并使用 StaticResource 重新使用它标记扩展是这样的 -

<Window.Resources>
   <Style>
      <Style x:Key="CommonButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="Visibility" Value="Visible"></Setter>
          <Style.Triggers>
              <DataTrigger Binding="{Binding ElementName=teachers,
                                       Path=SelectedItem}" 
                           Value="{x:Null}">
                    <Setter Property="Visibility" Value="Collapsed"></Setter>
              </DataTrigger>
          </Style.Triggers>
      </Style>
   </Style>
</Window.Resources>

并将其用于不同的按钮 -
<Button x:Name="Button1" Style="{StaticResource CommonButtonStyle}"/>
<Button x:Name="Button2" Style="{StaticResource CommonButtonStyle}"/>
<Button x:Name="Button3" Style="{StaticResource CommonButtonStyle}"/>

更新

万一ListView位于 Button 的可视树中的某处,您可以使用 RelativeSource在样式中,而不是使用 ElementName在绑定(bind)这样的东西 -
<DataTrigger Binding="{Binding Path=SelectedItem, RelativeSource={RelativeSource 
                                        FindAncestor, AncestorType=ListView}}" 
                           Value="{x:Null}">

但如果它们不相关,则需要使用 attached property将参数传递给样式。这个链接here可能会让你开始。

更新 2

我已经让它与附加属性一起工作,但修改了你的代码。这里是 -
public static class ThemeProperties
{
    public static object GetSelectedValue(DependencyObject obj)
    {
        return (object)obj.GetValue(SelectedValueProperty);
    }

    public static void SetSelectedValue(DependencyObject obj, object value)
    {
        obj.SetValue(SelectedValueProperty, value);
    }

    public static readonly DependencyProperty SelectedValueProperty =
        DependencyProperty.RegisterAttached("SelectedValue", typeof(object), 
          typeof(ThemeProperties), new FrameworkPropertyMetadata(null, 
           FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));     
}

XAML -
    <Style TargetType="{x:Type Button}" x:Key="cancelButton">
        <Setter Property="Visibility" Value="Visible"/>
        <Style.Triggers>
            <Trigger Property="local:ThemeProperties.SelectedValue"
                         Value="{x:Null}">
                <Setter Property="Visibility" Value="Collapsed"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

这是您的 ListView 和按钮 -
   <StackPanel>
        <ListView x:Name="lstView" ItemsSource="{Binding Objects}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button VerticalAlignment="Bottom" Height="30"  Width="100"
                local:ThemeProperties.SelectedValue="{Binding SelectedItem,
                            ElementName=lstView}"
                Style="{StaticResource cancelButton}"/>
    </StackPanel>

关于c# - WPF 可重用 Style.Triggers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13553890/

相关文章:

c# - 如何绘制选定的文本

c# - 在 WPF 中叠加两个位图图像

wpf - 如何在 MainWindow 上显示不同的 View

android - 使用 LiveData 时,为什么要在 ViewModel 类中双重声明变量?

c# - 为什么 Stack Trace 显示我的开发文件路径?

c# - 如何存储数十亿个 JSON 文件并进行查询

c# - 在.NET(C#或VB.NET)中生成摩尔斯电码(或任何音频),而无需第三方依赖,也无需使用音频文件

Wpf 工具包 AutoCompleteBox 在后台线程上搜索

WPF MVVM 控件错误地共享 ViewModel

c# - INotifyDataErrorInfo 和绑定(bind)异常