ListView: определить ItemsPanelTemplate в словаре ресурсов - PullRequest
9 голосов
/ 18 апреля 2011

У меня есть ListView, макет которого выглядит как представление Windows Explorer (значок + некоторые детали), привязанный к списку где-то в ViewModel.

Моя цель здесь - иметь возможность переключаться между видом проводника иликлассический вид, когда мы захотим.

Я мог бы определить ItemsPanelTemplate, выполняющий именно ту работу, которая правильно отображает макет, прямо в поле ListView.ItemsPanel.Теперь я хотел бы определить его в ресурсах, чтобы иметь возможность использовать его в разных представлениях, и особенно в одном элементе управления. У пользователя должен быть выбор между представлением Explorer или классическим представлением списка (рендеринг по умолчанию длясписок)

Как ты это сделал?Я не могу определить ItemsPanelTemplate в моем ResourceDictionary, и если я определю DataTemplate, он не совместим (хотя я думал, что, следуя чистой логике, ItemsPanelTemplate должен наследовать от DataTemplate, но на самом деле это не так.выглядит так).

Фрагмент кода для фактического списка:

<ListView SelectionMode="Single"
                VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Bottom"
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                ItemsSource="{Binding ListUserApps, 
                                UpdateSourceTrigger=PropertyChanged}" 
                SelectedIndex="{Binding SelectedUserApp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Background="White">

                <ListView.ItemsPanel>
                    <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}}" />
                        <!--MinWidth="{Binding ItemWidth,
                     RelativeSource={RelativeSource Self}}"-->
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>

                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" Height="Auto" Width="150">
                            <Image Source="{Binding Path=Appli.AppType, Converter={StaticResource TypeToIconConverter}}" Margin="5"
                                   Height="50" Width="50"/>
                            <StackPanel VerticalAlignment="Center" Width="90">
                                <TextBlock Text="{Binding Path=Appli.AppName}" 
                     FontSize="13" HorizontalAlignment="Left" TextWrapping="WrapWithOverflow"
                     Margin="0,0,0,1" />
                                <TextBlock Text="{Binding Path=Appli.AppType}" FontSize="9" 
                     HorizontalAlignment="Left" Margin="0,0,0,1" />
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>

            </ListView>

Хранить ItemTemplate в статическом ресурсе было легко, но теперь я ничего не могу сделать сthe ItemsPanelTemplate ...

Есть идеи?Я использую MVVM, поэтому в идеале я стараюсь не использовать выделенный код, если это возможно

1 Ответ

8 голосов
/ 18 апреля 2011

для этого вы бы использовали стиль для всего ListView.

, поэтому вы должны сделать:

<Grid.Resources>
  <Style x:Key="ListViewStyle" TargetType="ListView">
    <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}}" />
                        <!--MinWidth="{Binding ItemWidth,
                     RelativeSource={RelativeSource Self}}"-->
                    </ItemsPanelTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Grid.Resources>


    <ListView SelectionMode="Single"
        VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Bottom"
        ScrollViewer.VerticalScrollBarVisibility="Auto"
        ItemsSource="{Binding ListUserApps, 
                        UpdateSourceTrigger=PropertyChanged}" 
        SelectedIndex="{Binding SelectedUserApp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Background="White" Style="{StaticResource ListViewStyle}">                    
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Height="Auto" Width="150">
                    <Image Source="{Binding Path=Appli.AppType, Converter={StaticResource TypeToIconConverter}}" Margin="5"
                           Height="50" Width="50"/>
                    <StackPanel VerticalAlignment="Center" Width="90">
                        <TextBlock Text="{Binding Path=Appli.AppName}" 
             FontSize="13" HorizontalAlignment="Left" TextWrapping="WrapWithOverflow"
             Margin="0,0,0,1" />
                        <TextBlock Text="{Binding Path=Appli.AppType}" FontSize="9" 
             HorizontalAlignment="Left" Margin="0,0,0,1" />
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>            
    </ListView>

, если вы хотите, чтобы пользователь мог переключаться между проводником и классическим представлением, просто определите второй стиль и переключите стиль списка.Это можно сделать, например, с некоторыми VisualStates и DataStateBehavior.

В качестве альтернативы вы можете создать стиль с некоторыми DataTriggers и Setters для отдельных ItemsPanels.

...