自定义模板化列表框项触发器绑定到列表框

发布于 2024-12-08 07:04:14 字数 1453 浏览 1 评论 0原文

我有一个从 ListBox 继承的类和一个用于 ListBoxItems 的自定义 ControlTemplate。 如果条件成立,我想更改 ListBoxItems 背景。我尝试使用 DataTrigger 来实现此目的。我不想检查 ListBoxItems 上下文对象中的条件,我想在继承的 ListBox 类中检查它。

问题是,当需要在运行时确定每个 ListBoxItem 的正确值时,如何在 ControlTemplate 中将触发器绑定到 ListBox 属性?

    <Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="bd">
                        <TextBlock Name="lbl" Text="{Binding Path=DataChar}" FontWeight="ExtraBold" FontSize="15" Margin="5"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={ RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=IsSymbolExists}" Value="True">
                            <Setter TargetName="bd" Property="Background" Value="Yellow" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
    </Style>


public class CustomListBox : ListBox
{
 ...
     public bool IsSymbolExists
     {
          if(/*condition is true for the ListBoxItem*/)
              return true;
          return false;
     }
}

I have a class inherited from ListBox and a custom ControlTemplate for the ListBoxItems.
I want to change the ListBoxItems background if a condition is true. I tried to use DataTrigger for this. I don't want to check the condition in the ListBoxItems context object, I want to check it in the inherited ListBox class.

The question is how can I bind in the ControlTemplate the Trigger to a ListBox property, when it needs to decide the right value for each ListBoxItem in runtime?

    <Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="bd">
                        <TextBlock Name="lbl" Text="{Binding Path=DataChar}" FontWeight="ExtraBold" FontSize="15" Margin="5"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={ RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=IsSymbolExists}" Value="True">
                            <Setter TargetName="bd" Property="Background" Value="Yellow" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
    </Style>


public class CustomListBox : ListBox
{
 ...
     public bool IsSymbolExists
     {
          if(/*condition is true for the ListBoxItem*/)
              return true;
          return false;
     }
}

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

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

发布评论

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

评论(1

恋竹姑娘 2024-12-15 07:04:14

好的,首先有一些建议...

您的自定义列表框控件是否新属性(IsSymbolExists 等)而没有实际行为。如果是这样,请将它们声明为 附加属性

其次,当此值IsSymbolExists 变为 true ALL 其项目将通过黄色边框单独突出显示。这看起来不像是经过深思熟虑的 UI 行为。抱歉,如果这对您来说有点苛刻!

另外,从绑定角度来看,DataChar 属性看起来像是来自某个模型的基于数据上下文的属性 iee。如果是这样,那么它的绑定必须通过 ListBox 下的 ItemTemplate 完成,而不是在 ControlTemplate 下的 TextBlock 中完成。一个ListBoxItem。出于完全相同的原因,DataTriggerControlTemplate 中无法正常工作。

它们将在 ItemTemplate 中正常工作。

总而言之,您的代码需要以这种方式修复...

  1. 您可以摆脱 CustomListBox。创建一个名为 MyListBoxBehavior.IsSymbolExists 的布尔附加属性。将其附加到您的列表框。

  2. 您应该删除ListBoxItemControlTemplate

在 ListBox 中从中获取帮助...(此代码不会按原样编译):-)

    <ListBox local:MyListBoxBehavior.IsSymbolExists="{Binding WhateverBoolean}"
             ItemsSource="{Binding WhateverCollection}">
        <ListBox.ItemTemplate>
           <DataTemplate>
              <Border>
               <Border.Style>
                  <Style TargetType="{x:Type Border}">
                      <Style.Triggers>
                         <DataTrigger
                                Binding="{Binding
                                            RelativeSource={RelativeSource
                                               Mode=FindAncestor,
                                                 AncestorType={x:Type ListBox}},
                                        Path=local:MyListBoxBehavior.IsSymbolExists}"
                                Value="True">
                             <Setter Property="Background" Value="Yellow" />
                         </DataTrigger>
                      </Style.Triggers> 
                   </Style>
                </Border.Style> 
                <TextBlock Name="lbl"
                           Text="{Binding Path=DataChar}"
                           FontWeight="ExtraBold"
                           FontSize="15"
                           Margin="5"/>
              </Border>
           </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

希望这会有所帮助。

Ok firstly few suggestions...

Does your custom listbox control have only new properties (IsSymbolExists etc.) and no real behavior. If so please declare them as Attached Properties

Secondly when this value IsSymbolExists becomes true for a ListBox ALL its items will become highlighted individually by a yellow border. This doesnt look like a well thought UI behavior. Sorry if that comes to you as a bit harsh!

Also from the binding perspective the DataChar property looks like a data context based property i.e.e coming from some model. If so then its binding has to be done through an ItemTemplate under ListBox and not in a TextBlock under ControlTemplate of a ListBoxItem. And for exactly the same reason, DataTrigger wont work correctly in ControlTemplate.

They will work correctly in ItemTemplate.

So to summarize, your code needs to be fixed this way...

  1. You can get rid of CustomListBox. Create a boolean attached property called MyListBoxBehavior.IsSymbolExists. Attach it to your ListBox.

  2. You should get rid of ListBoxItem's ControlTemplate.

In ListBox take helpm from this... (this code wont compile as it is) :-)

    <ListBox local:MyListBoxBehavior.IsSymbolExists="{Binding WhateverBoolean}"
             ItemsSource="{Binding WhateverCollection}">
        <ListBox.ItemTemplate>
           <DataTemplate>
              <Border>
               <Border.Style>
                  <Style TargetType="{x:Type Border}">
                      <Style.Triggers>
                         <DataTrigger
                                Binding="{Binding
                                            RelativeSource={RelativeSource
                                               Mode=FindAncestor,
                                                 AncestorType={x:Type ListBox}},
                                        Path=local:MyListBoxBehavior.IsSymbolExists}"
                                Value="True">
                             <Setter Property="Background" Value="Yellow" />
                         </DataTrigger>
                      </Style.Triggers> 
                   </Style>
                </Border.Style> 
                <TextBlock Name="lbl"
                           Text="{Binding Path=DataChar}"
                           FontWeight="ExtraBold"
                           FontSize="15"
                           Margin="5"/>
              </Border>
           </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

Hope this helps.

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