I want to change the margin of the first item in the ListBox if SomeProperty value is 10, without code-behind. This is what I have so far:
<ListBox x:Class="Windows.CustomList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Windows"
mc:Ignorable="d" x:Name="MyList"
d:DesignHeight="300" d:DesignWidth="300">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=SomeProperty}" Value="10"/>
<Condition Binding="{Binding Path=Items.Count, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" Value="1" />
</MultiDataTrigger.Conditions>
<Setter Property="Margin">
<Setter.Value>
<Thickness Left="500"/>
</Setter.Value>
</Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<local:ListBoxItemCustomTemplate/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
When I try this approach I get:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='ListBox', AncestorLevel='1''. BindingExpression:Path=Items.Count; DataItem=null; target element is 'ListBox' (Name=''); target property is 'NoTarget' (type 'Object')
If I have only the first condition, it applies the margin properly. Another way I tried was by using the ElementName:
This approach doesn't give any error but it's not working either.
Any help would be much appreciated.
See
AlternationIndex
. (You can use a very highAlternationCount
to ensure that only the first item has index0
and trigger on that).This is a bit abusive, a cleaner method would be a value converter / multi value converter, that gets the index via something like
listBox.Items.IndexOf(currentItem)
.Another solution would be subclassing list box, and overriding PrepareContainerForItemOverride method. See my example below (it's for the Silverlight in WP7, so I had no AlternationIndex)..
Then I derive my items from ListBoxEx.iContainerStyle to get different margins for different items.