Wpf How to change List box ItemspanelTemplate using Trigger
Asked Answered
C

2

7

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.

Coprophilia answered 8/6, 2013 at 7:56 Comment(0)
B
10

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>
  ...
Beale answered 8/6, 2013 at 8:31 Comment(4)
Thanks a lot working Perfectly Fine and moreover i have changed StaticResource ratherthan DynamicResource and i'm stuck with one more issue when it aplies ListBoxWrapTemplate Actually images are not getting Wrapped instead its aligned Horzontally with HorizontalScroll bar.I don't want this HorizontalScroll bar but Images has to be Wrapped.Coprophilia
Is there any correction with the design to work ListBoxWraptemplate ?? please guide. Thanx.Coprophilia
@Coprophilia I think that's because the WrapPanel's Width does not force it to "wrap" as a quick guess try setting Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" on the WrapPanelBeale
Problem is with ViewBox Stretch="Fill" if i give Stretch="None" its working perfectly well. but i could'n figure out the root cause for this issue. May be it could be due to LayoutTransform because if i give Stretch = Fill the every image is taking the whole width of the ListBox .Do u have any idea behind this? .Thans a lot for ur reply.Coprophilia
I
2

I was wondering why Viv's answer did not work in my case :-( Here is what I did wrong:

Do not define the ItemsPanelTemplate appart from the <Style.Triggers> ! If you place one in the <Listbox.ItemPanel></Listbox.ItemPanel> the style triggers won't have any effect.

Arnaud.

ps: no sufficient reputation to only comment...

Inadvisable answered 3/2, 2015 at 10:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.