1. 程式人生 > >WPF ItemsControl ListBox ListView比較

WPF ItemsControl ListBox ListView比較

原文: WPF ItemsControl ListBox ListView比較

在進行列表資訊展示時,WPF中提供多種列表可供選擇。這篇部落格將對WPF ItemsControl, ListBox, ListView進行比較。

相同點:

1. 這三個控制元件都是列表型控制元件,可以進行列表繫結(ItemsSource);

2. 這三個控制元件均使用ItemsPresenter來展示列表資訊;

不同點:

控制元件層次關係:

ItemsControl:

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Control
              System.Windows.Controls.ItemsControl

ListBox:

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Control
              System.Windows.Controls.ItemsControl
                System.Windows.Controls.Primitives.Selector


                  System.Windows.Controls.ListBox

ListBox 繼承於ItemsControl,增加了一個Selector物件,ItemsControl中的Item是不支援選擇的。而ListBox中Item是支援選擇,並且可以單選,多選。

ListView:

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Control
              System.Windows.Controls.ItemsControl
                System.Windows.Controls.Primitives.Selector


                  System.Windows.Controls.ListBox
                    System.Windows.Controls.ListView

ListView繼承與ListBox,增加了一個View依賴屬性。

ItemsControl是不包含水平和垂直方向的滾動條的。ListBox和ListView有水平和垂直方向滾動條。

ItemControl的樣式:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="ItemsControlDefaultStyle" TargetType="{x:Type ItemsControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ItemsControl}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" 

Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <!-- Resource dictionary entries should be defined here. -->
</ResourceDictionary>

ListBox和ListView的樣式基本一樣,除了TargetType外,

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="ListBorder" Color="#828790"/>
    <Style x:Key="ListBoxDefaultStyle" TargetType="{x:Type ListBox}">
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
        <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" 

SnapsToDevicePixels="true">
                        <ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                        </Trigger>
                        <Trigger Property="IsGrouping" Value="true">
                            <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <!-- Resource dictionary entries should be defined here. -->
</ResourceDictionary>

在專案中如何選擇使用這三個控制元件;

1. 如果列表資訊只做展示,但不提供選擇功能,可以使用ItemsControl;

2. ListView比ListBox增加了一個View屬性。

示例程式碼:

ItemsControl vs ListBox (Selector)

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        
        <!--ItemsControl-->
        <StackPanel>
            <TextBlock Text="ItemsControl" FontSize="18"/>

            <ItemsControl ItemsSource="{Binding .}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Ellipse Width="110" Height="55" Fill="#ebebee"/>

                            <StackPanel>
                                <TextBlock Text="{Binding Priority}" FontSize="16" HorizontalAlignment="Center"/>
                                <TextBlock Text="{Binding Name}" FontSize="16" HorizontalAlignment="Center"/>
                            </StackPanel>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <ItemsControl.ItemContainerStyle>
                    <Style>
                        <Setter Property="Control.Margin" Value="5"/>
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ItemsControl>
        </StackPanel>

        <!--ListBox-->
        <StackPanel Grid.Row="1">
            <TextBlock Text="ListBox" FontSize="18"/>
            <ListBox ItemsSource="{Binding .}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Ellipse Width="110" Height="55" Fill="#ebebee"/>

                            <StackPanel>
                                <TextBlock Text="{Binding Priority}" FontSize="16" HorizontalAlignment="Center"/>
                                <TextBlock Text="{Binding Name}" FontSize="16" HorizontalAlignment="Center"/>
                            </StackPanel>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>

                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>

                <ListBox.ItemContainerStyle>
                    <Style>
                        <Setter Property="Control.Width" Value="120"/>
                        <Setter Property="Control.Margin" Value="5"/>
                    </Style>
                </ListBox.ItemContainerStyle>

                <ListBox.Template>
                    <ControlTemplate>
                        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                            <ItemsPresenter/>
                        </ScrollViewer>
                    </ControlTemplate>
                </ListBox.Template>
            </ListBox>
        </StackPanel>
    </Grid>

C#

    public class Task
    {
        public string Name { get; set; }

        public int Priority { get; set; }
    }

    ObservableCollection<Task> _tasks = null;
    public MainWindow()
    {
        InitializeComponent();

        _tasks = new ObservableCollection<Task>()
        {
            new Task() { Name = "Shopping",Priority = 2 },
            new Task() { Name = "Laundry",Priority = 2 },
            new Task() { Name = "Email",Priority = 1 },
            new Task() { Name = "Writting",Priority = 2 },
            new Task() { Name = "Learning",Priority = 2 },
            new Task() { Name = "Working",Priority = 2 },
        };

        DataContext = _tasks;
    }

執行效果:

ListView View屬性的使用

<ListView ItemsSource="{Binding .}">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="Task Name" DisplayMemberBinding="{Binding Name}" Width="100"/>
                <GridViewColumn Header="Task Priority" DisplayMemberBinding="{Binding Priority}" Width="100"/>
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

執行效果:

感謝您的閱讀,程式碼點選這裡下載。