在运行时更改ListBox的ItemsPanelTemplate

时间:2011-11-17 02:50:01

标签: c# silverlight xaml listbox itemspaneltemplate

我想在运行时更改ListBox的ItemsPanelTemplate。

我有以下XAML允许我更改ItemsPanelTemplate;但是有破坏ScrollViewer的不良副作用。

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ie="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

...

<UserControl.Resources>
    <ItemsPanelTemplate x:Key="StackPanelTemplate">
        <VirtualizingStackPanel/>
    </ItemsPanelTemplate>

    <ItemsPanelTemplate x:Key="WrapPanelTemplate">
        <telerik:RadWrapPanel/>
    </ItemsPanelTemplate>
</UserControl.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <StackPanel>
        <Button Content="StackPanel">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ie:ChangePropertyAction TargetName="TargetListBox" PropertyName="ItemsPanel" Value="{StaticResource StackPanelTemplate}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
        <Button Content="WrapPanel">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ie:ChangePropertyAction TargetName="TargetListBox" PropertyName="ItemsPanel" Value="{StaticResource WrapPanelTemplate}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </StackPanel>

    <ListBox x:Name="TargetListBox" Grid.Column="1" ItemsSource="{Binding SomeCollection}"/>
</Grid>

以这种方式更改ItemsPanelTemplate时。在您更改ScrollViewer之前,ScrollViewer似乎保持处于任何状态,并且使用滚动条不会对ListBox产生任何影响。

任何人都可以就此问题提供任何见解或提供解决方法吗?

谢谢。

*编辑*

因此,我已将问题缩小到与虚拟化相关的范围。如果仅为常规StackPanel更改VirtualizingStackPanel,则ScrollViewer不会中断。这对我来说不是一个真正的解决方案,因为这个ListBox将包含数百个搜索结果。

2 个答案:

答案 0 :(得分:1)

我认为最简单的解决方法是替换整个ListBox而不仅仅是面板模板。

答案 1 :(得分:0)

我正面临着同样的问题,我想创建一个包含产品的ListBox,让用户可以自由地将布局从WrapPanel更改为List框,从ListBox更改为WrapPanel。所以要做到这一点你应该使用样式。 (我建议你使用ListView而不是ListBox,因为ListBox中的滚动问题。无论如何两者都有效)。 首先在 app.xaml

中的 中添加2个样式

WrapPanelTemplateLV

<Style x:Key="WrapPanelTemplateLV" TargetType="ListView">
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
        </Style>

和StackPanelTemplateLV

<Style x:Key="StackPanelLV" TargetType="ListBox">
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <StackPanel />
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
        </Style>

现在你的按钮里面就是这样做

// StackPanelLV is on my App.xaml
            MyListView.Style = (Style)Application.Current.Resources["StackPanelLV"];

现在你明白了。制作一些逻辑来在两种风格之间切换。 我建议你再去讨论这个问题。 Changing the styles at runtime in WPF