开发者

custom templated listboxitem trigger bind to the listbox

开发者 https://www.devze.com 2023-04-09 23:03 出处:网络
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

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开发者_如何学Python 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;
     }
}


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号