自定义视图,设置默认ListView,ListViewItems默认样式
public class VirtualStackPanelView : ViewBase
{
public static readonly DependencyProperty OrientationProperty = VirtualStackPanel.OrientationProperty.AddOwner(typeof(VirtualStackPanelView)); public Orientation Orientation { get { return (Orientation)GetValue(OrientationProperty); } set { SetValue(OrientationProperty, value); } } public static readonly DependencyProperty SmallChangesProperty = VirtualStackPanel.SmallChangesProperty.AddOwner(typeof(VirtualStackPanelView)); public uint SmallChanges { get { return (uint)GetValue(SmallChangesProperty); } set { SetValue(SmallChangesProperty, value); } } public static readonly DependencyProperty ItemContainerStyleProperty = ItemsControl.ItemContainerStyleProperty.AddOwner(typeof(VirtualStackPanelView)); public Style ItemContainerStyle { get { return (Style)GetValue(ItemContainerStyleProperty); } set { SetValue(ItemContainerStyleProperty, value); } } public static readonly DependencyProperty ItemTemplateProperty = ItemsControl.ItemTemplateProperty.AddOwner(typeof(VirtualStackPanelView)); public DataTemplate ItemTemplate { get { return (DataTemplate)GetValue(ItemTemplateProperty); } set { SetValue(ItemTemplateProperty, value); } } public static readonly DependencyProperty ItemWidthProperty = VirtualStackPanel.ItemWidthProperty.AddOwner(typeof(VirtualStackPanelView)); public double ItemWidth { get { return (double)GetValue(ItemWidthProperty); } set { SetValue(ItemWidthProperty, value); } } public static readonly DependencyProperty ItemHeightProperty = VirtualStackPanel.ItemHeightProperty.AddOwner(typeof(VirtualStackPanelView)); public double ItemHeight { get { return (double)GetValue(ItemHeightProperty); } set { SetValue(ItemHeightProperty, value); } } public static readonly DependencyProperty HorizontalContentAlignmentProperty = StackPanel.HorizontalAlignmentProperty.AddOwner(typeof(VirtualStackPanelView)); public HorizontalAlignment HorizontalContentAlignment { get { return (HorizontalAlignment)GetValue(HorizontalContentAlignmentProperty); } set { SetValue(HorizontalContentAlignmentProperty, value); } } public static readonly DependencyProperty CacheItemCountProperty = DependencyProperty.Register("CacheItemCount", typeof(int), typeof(VirtualStackPanelView), new UIPropertyMetadata(0)); public int CacheItemCount { get { return (int)GetValue(CacheItemCountProperty); } set { SetValue(CacheItemCountProperty, value); } } private GridViewColumnCollection _columns = new GridViewColumnCollection(); public GridViewColumnCollection Columns { get { return _columns; } } public static readonly DependencyProperty ColumnHeaderContainerStyleProperty = GridView.ColumnHeaderContainerStyleProperty.AddOwner(typeof(VirtualStackPanelView)); public Style ColumnHeaderContainerStyle { get { return (Style)GetValue(ColumnHeaderContainerStyleProperty); } set { SetValue(ColumnHeaderContainerStyleProperty, value); } } public static readonly DependencyProperty ColumnHeaderTemplateSelectorProperty = GridView.ColumnHeaderTemplateSelectorProperty.AddOwner(typeof(VirtualStackPanelView)); public static readonly DependencyProperty ColumnHeaderStringFormatProperty = GridView.ColumnHeaderStringFormatProperty.AddOwner(typeof(VirtualStackPanelView)); public static readonly DependencyProperty AllowsColumnReorderProperty = GridView.AllowsColumnReorderProperty.AddOwner(typeof(VirtualStackPanelView)); public static readonly DependencyProperty ColumnHeaderContextMenuProperty = GridView.ColumnHeaderContextMenuProperty.AddOwner(typeof(VirtualStackPanelView)); public static readonly DependencyProperty ColumnHeaderToolTipProperty = GridView.ColumnHeaderToolTipProperty.AddOwner(typeof(VirtualStackPanelView)); protected override object DefaultStyleKey { get { return new ComponentResourceKey(GetType(), "virtualStackPanelViewDSK"); } } protected override object ItemContainerDefaultStyleKey { get { return new ComponentResourceKey(GetType(), "virtualStackPanelViewItemDSK"); } } }
查看ListView源码发现,当视图改变的时候,用当前视图的DefaultStyleKey,ItemContainerDefaultStyleKey设置ListView的默认样式和项容器样式,对于默认视图和我们自定义的视图
1 public class ListView : ListBox 2 { 3 public static readonly DependencyProperty ViewProperty; 4 private ViewBase _previousView; 5 public ViewBase View 6 { 7 get 8 { 9 return (ViewBase)base.GetValue(ListView.ViewProperty); 10 } 11 set 12 { 13 base.SetValue(ListView.ViewProperty, value); 14 } 15 } 16 static ListView() 17 { 18 ListView.ViewProperty = DependencyProperty.Register("View", typeof(ViewBase), typeof(ListView), new PropertyMetadata(new PropertyChangedCallback(ListView.OnViewChanged))); 19 ListBox.SelectionModeProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(SelectionMode.Extended)); 20 } 21 private static void OnViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 22 { 23 ListView listView = (ListView)d; 24 ViewBase viewBase = (ViewBase)e.OldValue; 25 ViewBase viewBase2 = (ViewBase)e.NewValue; 26 if (viewBase2 != null) 27 { 28 if (viewBase2.IsUsed) 29 { 30 throw new InvalidOperationException(SR.Get("ListView_ViewCannotBeShared")); 31 } 32 viewBase2.IsUsed = true; 33 } 34 listView._previousView = viewBase; 35 listView.ApplyNewView(); 36 listView._previousView = viewBase2; 37 ListViewAutomationPeer listViewAutomationPeer = UIElementAutomationPeer.FromElement(listView) as ListViewAutomationPeer; 38 if (listViewAutomationPeer != null) 39 { 40 if (listViewAutomationPeer.ViewAutomationPeer != null) 41 { 42 listViewAutomationPeer.ViewAutomationPeer.ViewDetached(); 43 } 44 if (viewBase2 != null) 45 { 46 listViewAutomationPeer.ViewAutomationPeer = viewBase2.GetAutomationPeer(listView); 47 } 48 else 49 { 50 listViewAutomationPeer.ViewAutomationPeer = null; 51 } 52 listViewAutomationPeer.InvalidatePeer(); 53 } 54 if (viewBase != null) 55 { 56 viewBase.IsUsed = false; 57 } 58 } 59 protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 60 { 61 base.PrepareContainerForItemOverride(element, item); 62 ListViewItem listViewItem = element as ListViewItem; 63 if (listViewItem != null) 64 { 65 ViewBase view = this.View; 66 if (view != null) 67 { 68 listViewItem.SetDefaultStyleKey(view.ItemContainerDefaultStyleKey); 69 view.PrepareItem(listViewItem); 70 return; 71 } 72 listViewItem.ClearDefaultStyleKey(); 73 } 74 } 75 private void ApplyNewView() 76 { 77 ViewBase view = this.View; 78 if (view != null) 79 { 80 base.DefaultStyleKey = view.DefaultStyleKey; 81 } 82 else 83 { 84 base.ClearValue(FrameworkElement.DefaultStyleKeyProperty); 85 } 86 if (base.IsLoaded) 87 { 88 base.ItemContainerGenerator.Refresh(); 89 } 90 } 91 }
定义ListView和ListViewItem的样式,自定义视图里的DefaultStyleKey和ItemContainerDefaultStyleKey就是我们这里设置的样式
1 <Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type uc:VirtualStackPanelView}, ResourceId=virtualStackPanelViewDSK}" 2 TargetType="{x:Type ListView}" 3 > 4 <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 5 6 <Setter Property="ItemContainerStyle" 7 Value="{Binding (ListView.View).ItemContainerStyle, 8 RelativeSource={RelativeSource Self}}"/> 9 10 <Setter Property="ItemTemplate" 11 Value="{Binding (ListView.View).ItemTemplate, 12 RelativeSource={RelativeSource Self}}"/> 13 <Setter Property="ItemsPanel"> 14 <Setter.Value> 15 <ItemsPanelTemplate> 16 <uc:VirtualStackPanel Width="{Binding (FrameworkElement.ActualWidth), 17 RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" 18 Orientation="{Binding (ListView.View).Orientation, RelativeSource={RelativeSource AncestorType=ListView}}" 19 SmallChanges="{Binding (ListView.View).SmallChanges, RelativeSource={RelativeSource AncestorType=ListView}}" 20 ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}" 21 MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}" 22 ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" 23 CacheItemCount="{Binding (ListView.View).CacheItemCount, RelativeSource={RelativeSource AncestorType=ListView}}" 24 /> 25 26 </ItemsPanelTemplate> 27 </Setter.Value> 28 </Setter> 29 </Style> 30 31 <Style x:Key="lvItemSelectStyle" TargetType="{x:Type ListViewItem}"> 32 <Style.Resources> 33 <ResourceDictionary Source="pack://application:,,,/QuickZip.UserControls;component/Themes/Brushes.xaml" /> 34 </Style.Resources> 35 <!--<Setter Property="Margin" Value="1,2,1,1"/>--> 36 <Setter Property="HorizontalAlignment" Value="Stretch" /> 37 <Setter Property="HorizontalContentAlignment" Value="Left" /> 38 <Setter Property="VerticalContentAlignment" Value="Stretch" /> 39 40 <!--<Setter Property="Background" Value="{TemplateBinding ListViewItem.Background}" />--> 41 <Setter Property="Template"> 42 <Setter.Value> 43 <ControlTemplate TargetType="{x:Type ListBoxItem}"> 44 <Border x:Name="border" BorderBrush="{StaticResource LightBorderBrush}" 45 BorderThickness="0" Padding="1" Background="{TemplateBinding Background}" > 46 <ContentPresenter Margin="5,0" /> 47 </Border> 48 <ControlTemplate.Triggers> 49 <MultiTrigger> 50 <MultiTrigger.Conditions> 51 <Condition Property="IsMouseOver" Value="True" /> 52 <Condition Property="IsSelected" Value="False"/> 53 </MultiTrigger.Conditions> 54 <Setter Property="Background" Value="{StaticResource HotTrackBrush}" /> 55 <Setter TargetName="border" Property="Padding" Value="0" /> 56 <Setter TargetName="border" Property="BorderThickness" Value="1" /> 57 </MultiTrigger> 58 <Trigger Property="IsSelected" Value="True"> 59 <Setter Property="Background" Value="{StaticResource SelectedBackgroundBrush}" /> 60 <Setter TargetName="border" Property="Padding" Value="0" /> 61 <Setter TargetName="border" Property="BorderThickness" Value="1" /> 62 </Trigger> 63 <Trigger Property="uc:SelectionHelper.IsDragging" Value="True"> 64 <Setter Property="Background" Value="{StaticResource HotTrackBrush}" /> 65 <Setter TargetName="border" Property="Padding" Value="0" /> 66 <Setter TargetName="border" Property="BorderThickness" Value="1" /> 67 </Trigger> 68 </ControlTemplate.Triggers> 69 </ControlTemplate> 70 </Setter.Value> 71 </Setter> 72 </Style> 73 74 <Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type uc:VirtualStackPanelView}, ResourceId=virtualStackPanelViewItemDSK}" 75 TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource lvItemSelectStyle}" > 76 </Style>
设置我们的视图,在视图中定义我么的ItemTemplate样式,用于填充项容器的ContentPresenter的内容
1 <uc:VirtualWrapPanelView x:Key="IconView" ColumnHeaderContainerStyle="{StaticResource ColumnHeaderContainerStyle}" 2 ItemHeight="{Binding RelativeSource={RelativeSource AncestorType=uc:FileList2}, Path=ViewSize, Converter={StaticResource iac}}" 3 ItemWidth="{Binding RelativeSource={RelativeSource AncestorType=uc:FileList2}, Path=ViewSize, Converter={StaticResource iac}}" 4 SmallChanges="{Binding Path=ItemHeight, RelativeSource={RelativeSource Self}}" 5 CacheItemCount="0" 6 HorizontalContentAlignment="Left" > 7 <uc:VirtualWrapPanelView.ItemTemplate> 8 <DataTemplate> 9 <DockPanel Margin="2,1,1,0"> 10 <Image 11 x:Name="img" DockPanel.Dock="Top" HorizontalAlignment="Center" Stretch= "UniformToFill" 12 Height="{Binding RelativeSource={RelativeSource AncestorType=uc:FileList2}, Path=ViewSize}" 13 Width="{Binding RelativeSource={RelativeSource AncestorType=uc:FileList2}, Path=ViewSize}" 14 Source="{Binding JumboIcon.Item2.Value}" 15 /> 16 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> 17 <uc:EditBox x:Name="eb" Margin="0,0" 18 DisplayValue="{Binding EmbeddedModel.Label}" 19 ActualValue="{Binding Name, Mode=TwoWay}" 20 IsEditable="{Binding EmbeddedModel.IsEditable}" 21 IsEditing="{Binding IsEditing, Mode=TwoWay}" 22 /> 23 <TextBlock Text="[*]" Visibility="{Binding EmbeddedModel.IsEncrypted, Converter={StaticResource btv}}" /> 24 </StackPanel> 25 </DockPanel> 26 </DataTemplate> 27 </uc:VirtualWrapPanelView.ItemTemplate> 28 <uc:VirtualWrapPanelView.Columns> 29 <GridViewColumn Width="100" Header="{x:Static trans:Texts.strHeaderFile}" uc:FileList2.SortPropertyName="sortByFullName" /> 30 <GridViewColumn Width="100" Header="{x:Static trans:Texts.strHeaderType}" uc:FileList2.SortPropertyName="sortByType" /> 31 <GridViewColumn Width="100" Header="{x:Static trans:Texts.strHeaderTime}" uc:FileList2.SortPropertyName="sortByLastWriteTime" /> 32 <GridViewColumn Width="100" Header="{x:Static trans:Texts.strHeaderSize}" uc:FileList2.SortPropertyName="sortByLength" /> 33 </uc:VirtualWrapPanelView.Columns> 34 </uc:VirtualWrapPanelView>