如何通过触发器在 ListView 为空时更改按钮图像

How to change Button Image when ListView is empty through a trigger

我想将 ListView 上的 WPF Button 图像更改为空,但我现在不知道这是我必须从触发器设置的 属性。

<Style x:Key="DisableOnEmptyLvStyle" TargetType="{x:Type Button}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding ElementName=myListView, Path=Items.Count}" Value="0">
            <Setter Property="IsEnabled" Value="False"/>
            <!-- which button property I must set here? -->
        </DataTrigger>
    </Style.Triggers>
</Style>

<Button Style="{StaticResource DisableOnEmptyLvStyle}">
    <Image Source="{StaticResource myImage}"/>
</Button>

一旦 ListView 有项目,则图像必须更改为正常图像。

知道怎么做吗?

请尝试以下操作:

<Style x:Key="DisableOnEmptyLvStyle" TargetType="{x:Type Button}">
<Setter Property="Content">
    <Setter.Value>
        <Image Source="{StaticResource myImageAtLeastOne}"/>
    </Setter.Value>
</Setter>
<Style.Triggers>
    <DataTrigger Binding="{Binding ElementName=myListView, Path=Items.Count}" Value="0">
        <Setter Property="IsEnabled" Value="False" />
        <Setter Property="Content">
            <Setter.Value>
                <Image Source="{StaticResource myImageEmpty}"/>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>
</Style>

<Button Style="{StaticResource DisableOnEmptyLvStyle}" />

您永远不应该直接使用 Style 设置 Content,因为 Style 被实例化一次并可能在多个控件中重复使用。问题是您在 Setter 中为 Content 分配的值也被实例化一次并且 shared,但是控件在 WPF 中只能有一个父级.

会出什么问题?如果您设置或更改样式中的 Content 并引用它,例如多个 Buttons 你会看到只有最后一个按钮显示图像。第一个按钮将其图像设置为 Content,然后下一个按钮将图像设置为 Content 并有效地删除第一个按钮的内容。

您可以考虑两种选择。

  1. 将图像创建为资源并通过将 x:Shared 属性设置为 False 强制 XAML 中的每个引用获取图像的新实例。 =28=]

    When set to false, modifies WPF resource-retrieval behavior so that requests for the attributed resource create a new instance for each request instead of sharing the same instance for all requests.

    <Window.Resources>
       <!-- ...your image sources for "myImage" and "myImage". -->
    
       <Image x:Key="myImageConrol" x:Shared="False"  Source="{StaticResource myImage}"/>
       <Image x:Key="myOtherImageConrol" x:Shared="False" Source="{StaticResource myImage}"/>
    
       <Style x:Key="DisableOnEmptyLvStyle" TargetType="{x:Type Button}">
          <Setter Property="Content" Value="{StaticResource myImageConrol}"/>
          <Style.Triggers>
             <DataTrigger Binding="{Binding ElementName=myListView, Path=Items.Count}" Value="0">
                <Setter Property="IsEnabled" Value="False" />
                <Setter Property="Content" Value="{StaticResource myOtherImageConrol}">
                </Setter>
             </DataTrigger>
          </Style.Triggers>
       </Style>
    </Window.Resources>
    
    <Button Style="{StaticResource DisableOnEmptyLvStyle}"/>
    
  2. 创建数据模板并将它们换出。这是有效的,因为 - 顾名思义 - 它们是模板,其控件将针对它们应用到的每个控件进行实例化。

    <Style x:Key="DisableOnEmptyLvStyle" TargetType="{x:Type Button}">
       <Setter Property="ContentTemplate">
          <Setter.Value>
             <DataTemplate>
                <Image Source="{StaticResource myImage}"/>
             </DataTemplate>
          </Setter.Value>
       </Setter>
       <Style.Triggers>
          <DataTrigger Binding="{Binding ElementName=myListView, Path=Items.Count}" Value="0">
             <Setter Property="IsEnabled" Value="False" />
             <Setter Property="ContentTemplate">
                <Setter.Value>
                   <DataTemplate>
                      <Image Source="{StaticResource myOtherImage}"/>
                   </DataTemplate>
                </Setter.Value>
             </Setter>
          </DataTrigger>
       </Style.Triggers>
    </Style>
    
    <Button Style="{StaticResource DisableOnEmptyLvStyle}"/>