C# 更改列表框';s ItemsPanelTemplate在运行时

C# 更改列表框';s ItemsPanelTemplate在运行时,c#,silverlight,xaml,listbox,itemspaneltemplate,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.

我希望在运行时更改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>
xmlns:i=“clr命名空间:System.Windows.Interactivity;assembly=System.Windows.Interactivity”
xmlns:ie=“clr命名空间:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactivity”
...
当您以这种方式更改ItemsPanelTemplate时。ScrollViewer似乎处于更改前的任何状态,使用滚动条不会对列表框产生任何更改

有谁能提供关于这个问题的见解,或者提供一个解决方法吗

多谢各位

*编辑*


因此,我将问题缩小到与虚拟化相关的问题。如果将VirtualzingStackPanel更改为常规StackPanel,则ScrollViewer不会中断。但这对我来说并不是一个真正的解决方案,因为这个列表框将容纳数百个搜索结果

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

我面临着同样的问题,我想创建一个包含产品的列表框,让用户可以自由地将布局从包装框更改为列表框,从列表框更改为包装框。所以要做到这一点,你应该使用样式。(我建议您使用ListView而不是ListBox,因为ListBox中存在滚动问题。无论如何,两者都可以工作)。 首先,在应用程序的中添加两种样式。xaml

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>
<Style x:Key="StackPanelLV" TargetType="ListBox">
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <StackPanel />
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
        </Style>
现在你有了主意。在这两种样式之间进行一些逻辑切换。 我建议你去这个问题了解更多。

谢谢您的回复。是的,我想过这个。当你说“替换”时,我想你的意思是有两个列表框并绑定它们的可见性?若有,;我希望会有一个更优雅的解决方案。我实际上在考虑从逻辑树中删除ListBox并在其位置插入另一个,或者您可以使用DataTemplateSelector(如Prism中的一个),根据您的习惯显示特定类型的ListBox。
// StackPanelLV is on my App.xaml
            MyListView.Style = (Style)Application.Current.Resources["StackPanelLV"];