Search code examples
wpflistboxitemspaneltemplate

Wpf How to change List box ItemspanelTemplate using Trigger


I need to set the ItemsPanelTemplate property of a ListBox based on a DependencyProperty on the control. How do I use the DataTemplateSelector to do that?

I have something like:

<ListBox.ItemsPanel>
   <ItemsPanelTemplate>
       <!-- Here I need to replace with either a StackPanel or a wrap panel-->
   </ItemsPanelTemplate>
</ListBox.ItemsPanel>

Here (ItemsPanelTemplate Selector in wpf?) is link with Similar Question. Below is my code but its not working:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <XmlDataProvider x:Key="myXmlDataBase" XPath="/myXmlData">
            <x:XData>
                <myXmlData xmlns="">
                    <Item Name = "CoverSheet" SNo="1"  Type="GrpBX" Image="C:\Work\00288511851128436163\N12201_0003_003\00000003.tif"/>
                    <Item Name = "HCFA" SNo="2" Type="GrpBX" Image="C:\Work\00288511851128436163\N12201_0003_003\00000004.tif"/>
                    <Item Name = "HCFA" SNo="3" Type="GrpBX" Image="C:\Work\00288511851128436163\N12201_0003_003\00000004.tif"/>
                    <Item Name = "HCFA" SNo="4" Type="GrpBX" Image="C:\Work\00288511851128436163\N12201_0003_003\00000004.tif"/>
                    <Item Name = "HCFA" SNo="5" Type="GrpBX" Image="C:\Work\00288511851128436163\N12201_0003_003\00000004.tif"/>
                    <Item Name = "HCFA" SNo="6" Type="GrpBX" Image="C:\Work\00288511851128436163\N12201_0003_003\00000004.tif"/>
                    <Item Name = "HCFA_CC" SNo="7" Type="GrpBX" Image="C:\Work\00288511851128436163\N12201_0003_003\00000005.tif"/>
                    <Item Name = "FrontPage" SNo="8" Type="GrpBX" Image="C:\Work\00288511851128436163\N12201_0003_003\N12201_0003_003I00.tif"/>
                </myXmlData>
            </x:XData>
        </XmlDataProvider>            
    </Window.Resources>

    <DockPanel>
        <ListBox Name="lv" ItemsSource="{Binding Source={StaticResource myXmlDataBase},XPath=Item}" FontSize="12" Background="LightGreen" ItemsPanel="{Binding RelativeSource={RelativeSource Self}, Path=Background}">
             <ListBox.Resources>                    
                 <Style x:Key="ListBoxWrapStyle" TargetType="ListBox">
                     <Setter Property="ItemsPanel">
                         <Setter.Value>
                             <ItemsPanelTemplate>
                                 <WrapPanel Width="{Binding FrameworkElement.ActualWidth),RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}" ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" />
                             </ItemsPanelTemplate>
                         </Setter.Value>
                     </Setter>
                 </Style>

                 <Style x:Key="ListBoxHorizontalStackStyle" TargetType="ListBox">
                     <Setter Property="ItemsPanel">
                         <Setter.Value>
                             <ItemsPanelTemplate>
                                <StackPanel  Width="{Binding (FrameworkElement.ActualWidth),RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" Orientation="Horizontal" />
                             </ItemsPanelTemplate>
                         </Setter.Value>
                     </Setter>
                 </Style>

                 <Style x:Key="ListBoxVerticalStackStyle" TargetType="ListBox">
                     <Setter Property="ItemsPanel">
                         <Setter.Value>
                             <ItemsPanelTemplate>
                                 <StackPanel Width="{Binding (FrameworkElement.ActualWidth),RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" Orientation="Vertical" />
                             </ItemsPanelTemplate>
                         </Setter.Value>
                     </Setter>
                 </Style>
             </ListBox.Resources>

             <ListBox.Style>
                 <Style TargetType="ListBox">
                     <Style.Triggers>
                         <!-- Your Trigger.. -->
                         <Trigger Property="Background" Value="Green">
                             <Setter Property="ItemsPanel" Value="{StaticResource ListBoxVerticalStackStyle}"/>
                         </Trigger>

                         <Trigger Property="Background" Value="LightBlue">
                             <Setter Property="ItemsPanel" Value="{StaticResource ListBoxHorizontalStackStyle}"/>
                         </Trigger>

                         <Trigger Property="Background" Value="LightGreen">
                             <Setter Property="ItemsPanel" Value="{StaticResource ListBoxWrapStyle}"/>
                         </Trigger>
                      </Style.Triggers>
                 </Style>
             </ListBox.Style>

             <ListBox.ItemTemplate>
                 <DataTemplate>
                     <Viewbox Stretch="Fill" HorizontalAlignment="Stretch" >
                         <Border BorderThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" DataContext="{Binding}" BorderBrush="IndianRed"   Margin="0" Height="Auto">
                            <DockPanel>
                                <Image 
                                    DockPanel.Dock="Top"
                                    Width="150" Margin="5"
                                    HorizontalAlignment="Stretch"
                                    VerticalAlignment="Stretch"
                                    Height="Auto"  x:Name="Myimage" 
                                    RenderOptions.BitmapScalingMode="HighQuality"  Source="{Binding XPath=@Image}">
                                </Image>

                                <Grid>
                                    <TextBlock Text="{Binding XPath=@SNo}" HorizontalAlignment="Center" FontWeight="Normal" FontSize="13" />
                                </Grid>
                            </DockPanel>
                        </Border>
                    </Viewbox>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </DockPanel>
</Window>

While running this code I'm getting ListBoxVerticalStackStyle'only.


Solution

  • As the error say's your trying to set a Style when it's expecting an ItemsPanelTemplate as Setter.Value. Define your resources as ItemPanelTemplate's than ListBox Style's and you should be sorted

    Try something like:

    <ListBox Name="lv"
              Background="LightBlue"
              FontSize="12"
              ItemsSource="{Binding Source={StaticResource myXmlDataBase},
                                    XPath=Item}">
      <ListBox.Resources>
        <ItemsPanelTemplate x:Key="ListBoxWrapTemplate">
          <WrapPanel Width="{Binding (FrameworkElement.ActualWidth),
                                      RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
                      ItemHeight="{Binding (ListView.View).ItemHeight,
                                          RelativeSource={RelativeSource AncestorType=ListView}}"
                      ItemWidth="{Binding (ListView.View).ItemWidth,
                                          RelativeSource={RelativeSource AncestorType=ListView}}" />
        </ItemsPanelTemplate>
        <ItemsPanelTemplate x:Key="ListBoxHorizontalStackTemplate">    
          <StackPanel Width="{Binding (FrameworkElement.ActualWidth),
                                      RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
                      Orientation="Horizontal" />    
        </ItemsPanelTemplate>
        <ItemsPanelTemplate x:Key="ListBoxVerticalStackTemplate">
          <StackPanel Width="{Binding (FrameworkElement.ActualWidth),
                                      RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
                      Orientation="Vertical" />
        </ItemsPanelTemplate>
      </ListBox.Resources>
      <ListBox.Style>
        <Style TargetType="ListBox">
          <Style.Triggers>
            <!--  Your Trigger..  -->
            <Trigger Property="Background"
                      Value="Green">
              <Setter Property="ItemsPanel"
                      Value="{DynamicResource ListBoxVerticalStackTemplate}" />
            </Trigger>
            <Trigger Property="Background"
                      Value="LightBlue">
              <Setter Property="ItemsPanel"
                      Value="{DynamicResource ListBoxHorizontalStackTemplate}" />
            </Trigger>
            <Trigger Property="Background"
                      Value="LightGreen">
              <Setter Property="ItemsPanel"
                      Value="{DynamicResource ListBoxWrapTemplate}" />
            </Trigger>
          </Style.Triggers>
        </Style>
      </ListBox.Style>
      ...