custom templated listboxitem trigger bind to the listbox
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...
You can get rid of
CustomListBox
. Create a boolean attached property calledMyListBoxBehavior.IsSymbolExists
. Attach it to your ListBox.You should get rid of
ListBoxItem
'sControlTemplate
.
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.
精彩评论