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

发布于 2025-01-16 15:11:06 字数 716 浏览 3 评论 0 原文

我想将 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 有项目,则图像必须更改为正常图像。

有什么想法如何做到这一点?

I would like to change the image of an WPF Button on ListView empty, but I don't now which is the property I must set from the trigger.

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

Once ListView has items, then the image must change to the normal one.

Any ideas how to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人生戏 2025-01-23 15:11:06

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

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

您可以考虑两种选择。

  1. 将图像创建为资源,并通过设置 x:Shared 属性设置为 False

    <块引用>

    当设置为 false 时,会修改 WPF 资源检索行为,以便对属性资源的请求为每个请求创建一个新实例,而不是为所有请求共享同一实例。

    ;
       
    
       
       
    
       
    

  2. 创建数据模板并交换它们。这是有效的,因为 - 顾名思义 - 它们是模板,并且其控件将为它们应用到的每个控件进行实例化。

    <样式 x:Key="DisableOnEmptyLvStyle" TargetType="{x:Type Button}">
       
          <设置器.值>
             <数据模板>
                <图像源=“{StaticResource myImage}”/>
             
          
       
       <样式.触发器>
          
             
             
                <设置器.值>
                   <数据模板>
                      <图像源=“{StaticResource myOtherImage}”/>
                   
                
             
          
       
    
    
    <按钮样式=“{StaticResourceDisableOnEmptyLvStyle}”/>
    

You should never set the Content directly using a Style, simply because the Style is instantiated once and potentially reused across multiple controls. The issue is that the value that you assign in the Setter for Content is also instantiated once and shared, but a control can only have a single parent in WPF.

What can go wrong? If you set or change the Content in a style and reference it for e.g. multiple Buttons you will see that only the last button shows the image. The first button gets its image set as Content, then the next button sets the image as Content and effectively removes the content of the first button.

There are two options that you can consider.

  1. Create the images as resources and force each reference in XAML to get a new instance of the image by setting the x:Shared attribute to False.

    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. Create data templates and swap them out. This works because - as the name says - they are templates and its controls will be instantiated for each control they are applied to.

    <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}"/>
    
梦初启 2025-01-23 15:11:06

请尝试以下操作:

<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}" />

Please try the following:

<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}" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文