如何:为 ListView 创建自定义视图模式

此示例演示如何为 ListView 控件创建自定义 View 模式。

ListView 控件创建自定义视图时,必须使用 ViewBase 类。 以下示例显示了一个名为 PlainView 的视图模式,该模式派生自 ViewBase 类。

public class PlainView : ViewBase
{

  public static readonly DependencyProperty
    ItemContainerStyleProperty =
    ItemsControl.ItemContainerStyleProperty.AddOwner(typeof(PlainView));

  public Style ItemContainerStyle
  {
      get { return (Style)GetValue(ItemContainerStyleProperty); }
      set { SetValue(ItemContainerStyleProperty, value); }
  }

  public static readonly DependencyProperty ItemTemplateProperty =
      ItemsControl.ItemTemplateProperty.AddOwner(typeof(PlainView));

  public DataTemplate ItemTemplate
  {
      get { return (DataTemplate)GetValue(ItemTemplateProperty); }
      set { SetValue(ItemTemplateProperty, value); }
  }

  public static readonly DependencyProperty ItemWidthProperty =
      WrapPanel.ItemWidthProperty.AddOwner(typeof(PlainView));

  public double ItemWidth
  {
      get { return (double)GetValue(ItemWidthProperty); }
      set { SetValue(ItemWidthProperty, value); }
  }

  public static readonly DependencyProperty ItemHeightProperty =
      WrapPanel.ItemHeightProperty.AddOwner(typeof(PlainView));

  public double ItemHeight
  {
      get { return (double)GetValue(ItemHeightProperty); }
      set { SetValue(ItemHeightProperty, value); }
  }

  protected override object DefaultStyleKey
  {
      get
      {
        return new ComponentResourceKey(GetType(), "myPlainViewDSK");
      }
  }
}
Public Class PlainView
    Inherits ViewBase

  Public Shared ReadOnly ItemContainerStyleProperty As DependencyProperty = ItemsControl.ItemContainerStyleProperty.AddOwner(GetType(PlainView))

  Public Property ItemContainerStyle() As Style
      Get
          Return CType(GetValue(ItemContainerStyleProperty), Style)
      End Get
      Set(ByVal value As Style)
          SetValue(ItemContainerStyleProperty, value)
      End Set
  End Property

  Public Shared ReadOnly ItemTemplateProperty As DependencyProperty = ItemsControl.ItemTemplateProperty.AddOwner(GetType(PlainView))

  Public Property ItemTemplate() As DataTemplate
      Get
          Return CType(GetValue(ItemTemplateProperty), DataTemplate)
      End Get
      Set(ByVal value As DataTemplate)
          SetValue(ItemTemplateProperty, value)
      End Set
  End Property

  Public Shared ReadOnly ItemWidthProperty As DependencyProperty = WrapPanel.ItemWidthProperty.AddOwner(GetType(PlainView))

  Public Property ItemWidth() As Double
      Get
          Return CDbl(GetValue(ItemWidthProperty))
      End Get
      Set(ByVal value As Double)
          SetValue(ItemWidthProperty, value)
      End Set
  End Property


  Public Shared ReadOnly ItemHeightProperty As DependencyProperty = WrapPanel.ItemHeightProperty.AddOwner(GetType(PlainView))

  Public Property ItemHeight() As Double
      Get
          Return CDbl(GetValue(ItemHeightProperty))
      End Get
      Set(ByVal value As Double)
          SetValue(ItemHeightProperty, value)
      End Set
  End Property


  Protected Overrides ReadOnly Property DefaultStyleKey() As Object
      Get
        Return New ComponentResourceKey(Me.GetType(), "myPlainViewDSK")
      End Get
  End Property

End Class

若要将样式应用于自定义视图,请使用 Style 类。 以下示例为 PlainView 视图模式定义 Style。 在前面的示例中,此样式设置为为 PlainView定义的 DefaultStyleKey 属性的值。

<Style x:Key="{ComponentResourceKey 
      TypeInTargetAssembly={x:Type l:PlainView},
      ResourceId=myPlainViewDSK}" 
       TargetType="{x:Type ListView}" 
       BasedOn="{StaticResource {x:Type ListBox}}"
       >
  <Setter Property="HorizontalContentAlignment"
          Value="Center"/>
  <Setter Property="ItemContainerStyle" 
          Value="{Binding (ListView.View).ItemContainerStyle,
          RelativeSource={RelativeSource Self}}"/>
  <Setter Property="ItemTemplate" 
          Value="{Binding (ListView.View).ItemTemplate,
          RelativeSource={RelativeSource Self}}"/>
  <Setter Property="ItemsPanel">
    <Setter.Value>
      <ItemsPanelTemplate>
        <WrapPanel Width="{Binding (FrameworkElement.ActualWidth),
                   RelativeSource={RelativeSource 
                                   AncestorType=ScrollContentPresenter}}"
                   ItemWidth="{Binding (ListView.View).ItemWidth,
                   RelativeSource={RelativeSource AncestorType=ListView}}"
                   MinWidth="{Binding (ListView.View).ItemWidth,
                   RelativeSource={RelativeSource AncestorType=ListView}}"
                   ItemHeight="{Binding (ListView.View).ItemHeight,
                   RelativeSource={RelativeSource AncestorType=ListView}}"/>
      </ItemsPanelTemplate>
    </Setter.Value>
  </Setter>
</Style>

若要在自定义视图模式下定义数据的布局,请定义 DataTemplate 对象。 以下示例定义一个 DataTemplate,可用于在 PlainView 视图模式下显示数据。

<DataTemplate x:Key="centralTile">
  <StackPanel Height="100" Width="90">
    <Grid Width="70" Height="70" HorizontalAlignment="Center">
      <Image Source="{Binding XPath=@Image}" Margin="6,6,6,9"/>
    </Grid>
    <TextBlock Text="{Binding XPath=@Name}" FontSize="13" 
               HorizontalAlignment="Center" Margin="0,0,0,1" />
    <TextBlock Text="{Binding XPath=@Type}" FontSize="9" 
               HorizontalAlignment="Center" Margin="0,0,0,1" />
  </StackPanel>
</DataTemplate>

以下示例展示如何为 PlainView 视图模式定义 ResourceKey,该模式使用了在前一示例中定义的 DataTemplate

<l:PlainView x:Key="tileView" 
             ItemTemplate="{StaticResource centralTile}" 
             ItemWidth="100"/>

如果将 View 属性设置为资源键,ListView 控件可以使用自定义视图。 以下示例演示如何将 PlainView 指定为 ListView的视图模式。

//Set the ListView View property to the tileView custom view
lv.View = lv.FindResource("tileView") as ViewBase;
'Set the ListView View property to the tileView custom view
lv.View = TryCast(lv.FindResource("tileView"), ViewBase)

有关完整示例,请参阅 具有多个视图的 ListView (C#)具有多个视图的 ListView (Visual Basic)

另请参阅