2011-11-17 6 views
3

런타임 중에 ListBox의 ItemsPanelTemplate을 변경하고 싶습니다.런타임시 ListBox의 ItemsPanelTemplate 변경

ItemsPanelTemplate을 변경할 수있는 다음 XAML이 있습니다. 그러나 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는 스크롤 막대를 사용하여 ListBox를 변경하기 전에 상태를 유지 한 것으로 보입니다.

누구든지이 문제에 대한 통찰력을 제공하거나 해결 방법을 제공 할 수 있습니까?

감사합니다. 이 가상화 관련되는 아래로

*이 EDIT *

그래서, 나는이 문제를 좁혀했습니다. 일반 StackPanel에 대한 VirtualizingStackPanel을 변경하면 ScrollViewer가 중단되지 않습니다. 이 ListBox는 수 백 가지의 검색 결과를 보유 할 것이기 때문에 이것은 실제로 저에게는 해결책이 아닙니다.

답변

1

가장 쉬운 해결 방법은 패널 템플릿 대신 전체 ListBox를 교체하는 것입니다.

+0

답해 주셔서 감사합니다. 네, 저는 이것을 생각했습니다. "대체"라고 말하면 두 개의 ListBox가 있고 가시성이 있다고 가정합니다. 그렇다면; 나는 더 우아한 해결책이 있기를 바랐다. – Dan

+0

사실 논리적 트리에서 ListBox를 제거하고 그 위치에 다른 하나를 삽입하는 것에 대해 생각하고있었습니다. 그렇지 않으면 프리즘 에서처럼 DataTemplateSelector를 사용하여 특정 유형의 ListBox를 표시 할 수 있습니다. –

0

글쎄 나는 제품이있는 ListBox를 만들고 사용자가 WrapPanel에서 ListBox로 그리고 ListBox에서 WrapPanel로 레이아웃을 자유롭게 바꿔야한다는 동일한 문제에 직면하고있었습니다. 이렇게하려면 스타일을 사용해야합니다. ListBox에서 스크롤하는 문제 때문에 ListBox가 아닌 ListView를 사용하는 것이 좋습니다. 어쨌든 둘 다 작동합니다. 처음에는

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> 

에게 app.xaml에 내부에이 스타일을 추가 그냥이

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

이제 아이디어를 얻었습니다. 2 가지 스타일 사이를 전환 할 수있는 논리를 만드십시오. 자세한 내용은이 질문으로 이동하는 것이 좋습니다. Changing the styles at runtime in WPF