芯片的ListBox和DataTrigger问题

发布于 2025-01-10 02:43:13 字数 4146 浏览 5 评论 0原文

我的 ListBoxItemDataTrigger 遇到问题。 我想在用鼠标单击 Chip 项目时更改 Chip 项目的 Background 颜色。

我认为问题出在这行代码中

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem},Path=IsSelected}"
             Value="True">
    <Setter Property="IconBackground"
            Value="#1b5eb2" />
    <Setter Property="Opacity"
            Value="1"></Setter>
</DataTrigger>

运行我的代码我得到了一个信号类别列表(如下面的屏幕截图所示):

信号类别水平列表作为芯片。

但是,当我用鼠标单击它们时圆圈的颜色不会改变。

它应该像这样工作(单击时):

带有选定圆圈的芯片(蓝色)。

我尝试了一些方法并检查了很多有关 DataTrigger 的主题,但我不能似乎明白了。

我的 .xaml 视图

<ListBox Name="SignalCategories"
         ItemsSource="{Binding DefinedSignalCategories}"
         SelectionMode="Single"
         HorizontalAlignment="Center"
         VerticalAlignment="Top"
         BorderThickness="0">

    <!--changing default ListBoxItem to hide selection highlight-->
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <ContentPresenter />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>

    <!--changing default orientation-->
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.ItemTemplate>
        <DataTemplate>
            <!--custom view-->
            <materialDesign:Chip Content="{Binding Name}"
                                 Margin="5"
                                 IconForeground="{DynamicResource PrimaryHueDarkForegroundBrush}">
                <materialDesign:Chip.Style>
                    <Style TargetType="{x:Type materialDesign:Chip}">
                        <Setter Property="Opacity"
                                Value="0.85" />
                        <Setter Property="IconBackground"
                                Value="Gray"></Setter>
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver"
                                     Value="True">
                                <Setter Property="Opacity"
                                        Value="1" />
                                <Setter Property="IconBackground"
                                        Value="#1b5eb2">
                                </Setter>
                            </Trigger>
                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem},Path=IsSelected}"
                                         Value="True">
                                <Setter Property="IconBackground"
                                        Value="#1b5eb2" />
                                <Setter Property="Opacity"
                                        Value="1"></Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </materialDesign:Chip.Style>
                <materialDesign:Chip.Icon>
                    <materialDesign:PackIcon Kind="{Binding IconName}" />
                </materialDesign:Chip.Icon>
            </materialDesign:Chip>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

I have a problem with ListBoxItem and DataTrigger.
I want to change the Background color of my Chip item when the chip item is clicked with the mouse.

I think the problem is in this line of code

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem},Path=IsSelected}"
             Value="True">
    <Setter Property="IconBackground"
            Value="#1b5eb2" />
    <Setter Property="Opacity"
            Value="1"></Setter>
</DataTrigger>

Running my code I got a list of signals category (like in the screenshot below):

Horizontal list of signal categories as Chips.

However, when I click on them with my mouse the color of the circle does not change.

It should be working like this (when clicked):

Chip with selected circle (blue).

I tried a couple of things and checked a lot of topics about DataTrigger, but i can't seem to figure it out.

My .xaml view

<ListBox Name="SignalCategories"
         ItemsSource="{Binding DefinedSignalCategories}"
         SelectionMode="Single"
         HorizontalAlignment="Center"
         VerticalAlignment="Top"
         BorderThickness="0">

    <!--changing default ListBoxItem to hide selection highlight-->
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <ContentPresenter />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>

    <!--changing default orientation-->
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.ItemTemplate>
        <DataTemplate>
            <!--custom view-->
            <materialDesign:Chip Content="{Binding Name}"
                                 Margin="5"
                                 IconForeground="{DynamicResource PrimaryHueDarkForegroundBrush}">
                <materialDesign:Chip.Style>
                    <Style TargetType="{x:Type materialDesign:Chip}">
                        <Setter Property="Opacity"
                                Value="0.85" />
                        <Setter Property="IconBackground"
                                Value="Gray"></Setter>
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver"
                                     Value="True">
                                <Setter Property="Opacity"
                                        Value="1" />
                                <Setter Property="IconBackground"
                                        Value="#1b5eb2">
                                </Setter>
                            </Trigger>
                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem},Path=IsSelected}"
                                         Value="True">
                                <Setter Property="IconBackground"
                                        Value="#1b5eb2" />
                                <Setter Property="Opacity"
                                        Value="1"></Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </materialDesign:Chip.Style>
                <materialDesign:Chip.Icon>
                    <materialDesign:PackIcon Kind="{Binding IconName}" />
                </materialDesign:Chip.Icon>
            </materialDesign:Chip>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

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

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

发布评论

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

评论(2

乜一 2025-01-17 02:43:13

这不起作用的原因是您滥用了 Chip 控件。它是派生自 ButtonBase,这意味着它基本上是一个按钮。它处理鼠标单击事件,这会设置 将相应路由事件参数的e.Handled 标志设置为true。请参阅Handled 的概念供参考。

Handled 的值会影响路由事件在沿路线进一步传播时的报告或处理方式。如果路由事件的事件数据中的 Handledtrue,则通常不再为该特定事件实例调用在其他元素上侦听该路由事件的处理程序。< /p>

因此,Chip 上的单击会被 ListBoxItem 忽略,因此不会被选中。当然,您可以使用在代码隐藏中使用 handledEventsToo 注册点击处理程序的解决方法,如本文所述,然后在可视化树中搜索 ListBoxItem 并设置 < code>IsSelected 为 true,但我不推荐它,因为它首先是错误的控件。由于 Chip 是一个按钮,因此它具有“鼠标悬停”和“按下”的视觉状态以及其他状态和大量您不需要或不需要的标记必须重写才能使按钮表现得好像它不是一个按钮。这没有道理。

您可以做的是 复制Chip 的默认样式的要点,并用它制作一个 DataTemplate 或自定义控件。以下数据模板应该适合您。

<ListBox.ItemTemplate>
   <DataTemplate>
      <Grid>
         <Grid.Resources>
            <materialDesign:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter" />
            <materialDesign:PackIcon x:Key="Icon"
                                     Kind="{Binding IconName}" />
         </Grid.Resources>
         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
         </Grid.ColumnDefinitions>
         <Border CornerRadius="16"
                 Background="{DynamicResource MaterialDesignChipBackground}"
                 Grid.ColumnSpan="3" />
         <ContentControl Grid.Column="0"
                         Content="{StaticResource Icon}"
                         Background="{DynamicResource PrimaryHueMidBrush}"
                         FontSize="17"
                         FontWeight="Regular"
                         IsTabStop="False"
                         Visibility="{Binding Source={StaticResource Icon}, Converter={StaticResource NullableToVisibilityConverter}}"
                         VerticalAlignment="Center"
                         VerticalContentAlignment="Center"
                         HorizontalContentAlignment="Center"
                         Height="32"
                         Width="32">
            <ContentControl.Style>
               <Style TargetType="{x:Type ContentControl}">
                  <Setter Property="Foreground" Value="{DynamicResource PrimaryHueMidForegroundBrush}"></Setter>
                  <Style.Triggers>
                     <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                                  Value="True">
                        <Setter Property="Foreground"
                                Value="White" />
                     </DataTrigger>
                     <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem},Path=IsSelected}"
                                  Value="True">
                        <Setter Property="Foreground"
                                Value="White" />
                     </DataTrigger>
                  </Style.Triggers>
               </Style>
            </ContentControl.Style>
            <ContentControl.Clip>
               <EllipseGeometry RadiusX="16"
                                RadiusY="16"
                                Center="16,16" />
            </ContentControl.Clip>
            <ContentControl.Template>
               <ControlTemplate TargetType="ContentControl">
                  <Border x:Name="ChipBackgroundBorder"
                          Background="{DynamicResource MaterialDesignChipBackground}">
                     <ContentPresenter Content="{TemplateBinding Content}"
                                       HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                       VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                  </Border>
                  <ControlTemplate.Triggers>
                     <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                                  Value="True">
                        <Setter TargetName="ChipBackgroundBorder"
                                Property="Opacity"
                                Value="1" />
                        <Setter TargetName="ChipBackgroundBorder"
                                Property="Background"
                                Value="#1b5eb2" />
                     </DataTrigger>
                     <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem},Path=IsSelected}"
                                  Value="True">
                        <Setter TargetName="ChipBackgroundBorder"
                                Property="Background"
                                Value="#1b5eb2" />
                        <Setter TargetName="ChipBackgroundBorder"
                                Property="Opacity"
                                Value="1" />
                     </DataTrigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </ContentControl.Template>
         </ContentControl>
         <ContentControl Content="{Binding Name}"
                         x:Name="TextBlock"
                         IsTabStop="False"
                         VerticalAlignment="Center"
                         Margin="8 0 12 0"
                         Grid.Column="1" />
      </Grid>
   </DataTemplate>
</ListBox.ItemTemplate>

此模板与您的用例的 Chip 模板几乎相同,但是,您可能需要考虑创建自己的模板并对其进行大幅简化,以满足您的需求。

The reason why this does not work is that you are misusing the Chip control. It is a type derived from ButtonBase, which means it is basically a button. It handles mouse click events, which sets the e.Handled flag of the corresponding routed event arguments to true. See The Concept of Handled for reference.

The value of Handled affects how a routed event is reported or processed as it travels further along the route. If Handled is true in the event data for a routed event, then handlers that listen for that routed event on other elements are generally no longer invoked for that particular event instance.

Consequently, the click on the Chip is ignored by the ListBoxItem and is therefore not selected. You could of course use the workaround of registering a click handler in code-behind with handledEventsToo as described in the article and then search up the visual tree for a ListBoxItem and set IsSelected to true, but I would not recommend it, since it is the wrong control to use in the first place. As Chip is a button, it has visual states for Mouse Over and Pressed and other states and lots of markup that you either do not need or have to override in order to make the button act as if it was not a button. That does not make sense.

What you can do instead is copy the essentials of the default style for Chip and make a DataTemplate or a custom control out of it. The following data template should work for you.

<ListBox.ItemTemplate>
   <DataTemplate>
      <Grid>
         <Grid.Resources>
            <materialDesign:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter" />
            <materialDesign:PackIcon x:Key="Icon"
                                     Kind="{Binding IconName}" />
         </Grid.Resources>
         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
         </Grid.ColumnDefinitions>
         <Border CornerRadius="16"
                 Background="{DynamicResource MaterialDesignChipBackground}"
                 Grid.ColumnSpan="3" />
         <ContentControl Grid.Column="0"
                         Content="{StaticResource Icon}"
                         Background="{DynamicResource PrimaryHueMidBrush}"
                         FontSize="17"
                         FontWeight="Regular"
                         IsTabStop="False"
                         Visibility="{Binding Source={StaticResource Icon}, Converter={StaticResource NullableToVisibilityConverter}}"
                         VerticalAlignment="Center"
                         VerticalContentAlignment="Center"
                         HorizontalContentAlignment="Center"
                         Height="32"
                         Width="32">
            <ContentControl.Style>
               <Style TargetType="{x:Type ContentControl}">
                  <Setter Property="Foreground" Value="{DynamicResource PrimaryHueMidForegroundBrush}"></Setter>
                  <Style.Triggers>
                     <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                                  Value="True">
                        <Setter Property="Foreground"
                                Value="White" />
                     </DataTrigger>
                     <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem},Path=IsSelected}"
                                  Value="True">
                        <Setter Property="Foreground"
                                Value="White" />
                     </DataTrigger>
                  </Style.Triggers>
               </Style>
            </ContentControl.Style>
            <ContentControl.Clip>
               <EllipseGeometry RadiusX="16"
                                RadiusY="16"
                                Center="16,16" />
            </ContentControl.Clip>
            <ContentControl.Template>
               <ControlTemplate TargetType="ContentControl">
                  <Border x:Name="ChipBackgroundBorder"
                          Background="{DynamicResource MaterialDesignChipBackground}">
                     <ContentPresenter Content="{TemplateBinding Content}"
                                       HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                       VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                  </Border>
                  <ControlTemplate.Triggers>
                     <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                                  Value="True">
                        <Setter TargetName="ChipBackgroundBorder"
                                Property="Opacity"
                                Value="1" />
                        <Setter TargetName="ChipBackgroundBorder"
                                Property="Background"
                                Value="#1b5eb2" />
                     </DataTrigger>
                     <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem},Path=IsSelected}"
                                  Value="True">
                        <Setter TargetName="ChipBackgroundBorder"
                                Property="Background"
                                Value="#1b5eb2" />
                        <Setter TargetName="ChipBackgroundBorder"
                                Property="Opacity"
                                Value="1" />
                     </DataTrigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </ContentControl.Template>
         </ContentControl>
         <ContentControl Content="{Binding Name}"
                         x:Name="TextBlock"
                         IsTabStop="False"
                         VerticalAlignment="Center"
                         Margin="8 0 12 0"
                         Grid.Column="1" />
      </Grid>
   </DataTemplate>
</ListBox.ItemTemplate>

This template is almost identical to the Chip template for your use-case, however, you might want to consider creating your own template and simplify it drastically to fit your requirements only.

木槿暧夏七纪年 2025-01-17 02:43:13

我发现问题似乎出在 materialDesign:Chip 上。
我在没有使用materialDesign的情况下重做了它,现在它可以正常工作了。

工作代码:

<ListBox.ItemTemplate>
<DataTemplate>
    <!--custom view-->
    <Grid Width="auto"
          Height="30"
          x:Name="grid1"
          Margin="10">
        <Border BorderBrush="Transparent"
                HorizontalAlignment="Left"
                Background="#939393"
                Panel.ZIndex="1000"
                BorderThickness="0"
                CornerRadius="30"
                Width="30"
                Height="30"
                x:Name="BorderCircle">
            <materialDesign:PackIcon Kind="{Binding IconName}"
                                     Margin="5"
                                     VerticalAlignment="Center"
                                     HorizontalAlignment="Center"
                                     Foreground="White" />
        </Border>
        <Border Background="#efefef"
                BorderThickness="0"
                CornerRadius="15"
                HorizontalAlignment="Right"
                Margin="10 0 0 0">

            <TextBlock Text="{Binding Name}"
                       HorizontalAlignment="Right"
                       VerticalAlignment="Center"
                       Margin="25 0 10 0" />
        </Border>
    </Grid>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
                     Value="True">
            <Setter TargetName="BorderCircle"
                    Property="Background"
                    Value="#1b5eb2" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

输出:
输入图片此处描述

I figured it out looks like the problem is with materialDesign:Chip.
I've redone it without using materialDesign and now it's working correctly.

Working Code:

<ListBox.ItemTemplate>
<DataTemplate>
    <!--custom view-->
    <Grid Width="auto"
          Height="30"
          x:Name="grid1"
          Margin="10">
        <Border BorderBrush="Transparent"
                HorizontalAlignment="Left"
                Background="#939393"
                Panel.ZIndex="1000"
                BorderThickness="0"
                CornerRadius="30"
                Width="30"
                Height="30"
                x:Name="BorderCircle">
            <materialDesign:PackIcon Kind="{Binding IconName}"
                                     Margin="5"
                                     VerticalAlignment="Center"
                                     HorizontalAlignment="Center"
                                     Foreground="White" />
        </Border>
        <Border Background="#efefef"
                BorderThickness="0"
                CornerRadius="15"
                HorizontalAlignment="Right"
                Margin="10 0 0 0">

            <TextBlock Text="{Binding Name}"
                       HorizontalAlignment="Right"
                       VerticalAlignment="Center"
                       Margin="25 0 10 0" />
        </Border>
    </Grid>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
                     Value="True">
            <Setter TargetName="BorderCircle"
                    Property="Background"
                    Value="#1b5eb2" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

Output:
enter image description here

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