有的代码是大神提供的,只是整理了一下
效果
修改GridLine是否可见,以及线宽:
<Visibility x:Key="ListView.GridLine.Horizontal.Visibility">Collapsed</Visibility>
<Visibility x:Key="ListView.GridLine.Vertical.Visibility">Collapsed</Visibility>
<!--<Visibility x:Key="ListView.GridLine.Horizontal.Visibility">Visible</Visibility>-->
<!--<Visibility x:Key="ListView.GridLine.Vertical.Visibility">Visible</Visibility>-->
<sys:Double x:Key="ListView.GridLine.Horizontal.Width">2</sys:Double>
<sys:Double x:Key="ListView.GridLine.Vertical.Width">1</sys:Double>
<!--第3个值(右边间距)必须和列线width相同-->
<Thickness x:Key="ListView.Thumb.Margin">0,0,-1,0</Thickness>
<sys:Double x:Key="ListView.Header.Height">40</sys:Double>
<SolidColorBrush x:Key="ListView.Header.Background">#80365080</SolidColorBrush>
<SolidColorBrush x:Key="ListView.Header.Foreground">#80FFFFFF</SolidColorBrush>
Style:
<Window x:Class="ListViewTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ListViewTest"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="500" Width="790">
<Window.Resources>
<local:V2VConveter x:Key="V2V"/>
<XmlDataProvider x:Key="People">
<x:XData>
<People xmlns="">
<Person>
<Name>Peter</Name>
<Surname>Black</Surname>
<Age>25</Age>
</Person>
<Person>
<Name>John</Name>
<Surname>Smith</Surname>
<Age>35</Age>
</Person>
<Person>
<Name>tom</Name>
<Surname>cat</Surname>
<Age>15</Age>
</Person>
<Person>
<Name>TELL</Name>
<Surname>Ahalp</Surname>
<Age>34</Age>
</Person>
<Person>
<Name>JODan</Name>
<Surname>JD</Surname>
<Age>54</Age>
</Person>
<Person>
<Name>Jams</Name>
<Surname>Js</Surname>
<Age>37</Age>
</Person>
<Person>
<Name>WeiDe</Name>
<Surname>WD</Surname>
<Age>39</Age>
</Person>
<Person>
<Name>YaoMing</Name>
<Surname>YM</Surname>
<Age>37</Age>
</Person>
</People>
</x:XData>
</XmlDataProvider>
<!--GridLine-->
<Visibility x:Key="ListView.GridLine.Horizontal.Visibility">Collapsed</Visibility>
<Visibility x:Key="ListView.GridLine.Vertical.Visibility">Collapsed</Visibility>
<!--<Visibility x:Key="ListView.GridLine.Horizontal.Visibility">Visible</Visibility>-->
<!--<Visibility x:Key="ListView.GridLine.Vertical.Visibility">Visible</Visibility>-->
<sys:Double x:Key="ListView.GridLine.Horizontal.Width">2</sys:Double>
<sys:Double x:Key="ListView.GridLine.Vertical.Width">1</sys:Double>
<!--第3个值(右边坚决)必须和列线width相同-->
<Thickness x:Key="ListView.Thumb.Margin">0,0,-1,0</Thickness>
<sys:Double x:Key="ListView.Header.Height">40</sys:Double>
<SolidColorBrush x:Key="ListView.Header.Background">#80365080</SolidColorBrush>
<SolidColorBrush x:Key="ListView.Header.Foreground">#80FFFFFF</SolidColorBrush>
<LinearGradientBrush x:Key="ListView.GridLine.Horizontal.Brush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Orange" Offset="0"/>
<GradientStop Color="Black" Offset="0.5"/>
<GradientStop Color="Orange" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ListView.GridLine.Horizontal.MouseOver.Brush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="OrangeRed" Offset="0"/>
<GradientStop Color="WhiteSmoke" Offset="0.5"/>
<GradientStop Color="OrangeRed" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ListView.GridLine.Vertical.Brush" StartPoint="0,0" EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="WhiteSmoke" Offset="0"/>
<GradientStop Color="Black" Offset="0.5"/>
<GradientStop Color="WhiteSmoke" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<Style x:Key="ListViewHeaderThumb" TargetType="Thumb">
<Setter Property="Background" Value="Chocolate"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}" Background="Transparent" Width="10"
Margin="{StaticResource ListView.Thumb.Margin}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle Width="{StaticResource ListView.GridLine.Vertical.Width}"
Fill="{StaticResource ListView.GridLine.Vertical.Brush}"
HorizontalAlignment="Right" VerticalAlignment="Stretch"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DefaultListViewHeader" TargetType="GridViewColumnHeader">
<Setter Property="Foreground" Value="{StaticResource ListView.Header.Foreground}"/>
<Setter Property="Background" Value="{StaticResource ListView.Header.Background}"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Height" Value="{StaticResource ListView.Header.Height}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Green"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Border x:Name="HeaderBorder" Padding="0" Margin="0,0,0,0"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="HeaderContent" Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Margin="0" RecognizesAccessKey="True"
HorizontalAlignment="Center" VerticalAlignment="Center"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Thumb x:Name="PART_HeaderGripper" Grid.Column="1" HorizontalAlignment="Right"
Style="{StaticResource ListViewHeaderThumb}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsDragging, ElementName=PART_HeaderGripper}" Value="True">
<Setter Property="Foreground" Value="Lavender"/>
<Setter Property="FontSize" Value="20"/>
<Setter TargetName="HeaderBorder" Property="Background" Value="Violet"/>
</DataTrigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="HeaderContent" Property="Margin" Value="6,1,6,1" />
<Setter Property="Foreground" Value="Cyan"/>
<Setter Property="FontSize" Value="20"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock TextBlock.FontWeight="SemiBold" Text="{Binding}" TextAlignment="Center"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Role" Value="Floating">
<Setter Property="Opacity" Value="0.7"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Canvas Name="PART_FloatingHeaderCanvas">
<Rectangle Fill="#60000000" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}" />
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DefaultGridViewScrollViewerStyle" TargetType="{x:Type ScrollViewer}" BasedOn="{StaticResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Margin="{TemplateBinding Padding}">
<ScrollViewer DockPanel.Dock="Top" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<GridViewHeaderRowPresenter AllowsColumnReorder="{Binding TemplatedParent.View.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderContainerStyle="{Binding TemplatedParent.View.ColumnHeaderContainerStyle, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderToolTip="{Binding TemplatedParent.View.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderStringFormat="{Binding TemplatedParent.View.ColumnHeaderStringFormat, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderContextMenu="{Binding TemplatedParent.View.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderTemplate="{Binding TemplatedParent.View.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}"
Columns="{Binding TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderTemplateSelector="{Binding TemplatedParent.View.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}"
Margin="0" Visibility="Visible" x:Name="PART_Header" Height="auto"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
CanContentScroll="{TemplateBinding CanContentScroll}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
KeyboardNavigation.DirectionalNavigation="Local"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</DockPanel>
<ScrollBar x:Name="PART_HorizontalScrollBar" Cursor="Arrow" Maximum="{TemplateBinding ScrollableWidth}"
Minimum="0.0" Orientation="Horizontal" Grid.Row="1"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportWidth}" />
<ScrollBar x:Name="PART_VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}"
Minimum="0.0" Orientation="Vertical"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportHeight}" />
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Columns, ElementName=PART_Header}" Value="{x:Null}">
<Setter Property="Visibility" TargetName="PART_Header" Value="Collapsed"></Setter>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel Orientation="Vertical">
<ListView Name="PeopleList"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Source={StaticResource People},XPath=/People/Person}"
BorderThickness="0" BorderBrush="Black"
ScrollViewer.CanContentScroll="True"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
ScrollViewer.IsDeferredScrollingEnabled="False"
OverridesDefaultStyle="true"
SelectionMode="Single"
AlternationCount="2">
<ListView.Template>
<ControlTemplate TargetType="{x:Type ListView}">
<Border x:Name="Border" SnapsToDevicePixels="true"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Padding="{TemplateBinding Padding}" Style="{StaticResource DefaultGridViewScrollViewerStyle}">
<ItemsPresenter/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Opacity" Value="0.4" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ListView.Template>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<!--也可以通过BorderThickness和BorderBrush的Bottom设置水平线条宽度和颜色-->
<Setter Property="BorderBrush" Value="LightGray"/>
<Setter Property="BorderThickness" Value="0,0,0,0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<local:GridViewRowPresenterWithGridLines Height="60"
Columns="{TemplateBinding GridView.ColumnCollection}"
Margin="{TemplateBinding Padding}"
GridLineWidth="{StaticResource ListView.GridLine.Vertical.Width}"
GridLineBrush="{StaticResource ListView.GridLine.Vertical.Brush}"
GridLinesVisibility="{StaticResource ListView.GridLine.Horizontal.Visibility}"/>
<!--水平线条-->
<Rectangle x:Name="horLine" Grid.Row="1" Height="{StaticResource ListView.GridLine.Horizontal.Width}"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
Fill="{StaticResource ListView.GridLine.Horizontal.Brush}"
Visibility="{StaticResource ListView.GridLine.Vertical.Visibility}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<!--设置隔行背景-->
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter TargetName="border" Property="Background" Value="#50e9e9e9"/>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter TargetName="border" Property="Background" Value="#FFe9e9e9"/>
</Trigger>
<!--鼠标经过-->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="#D0BA7DF4"/>
<Setter TargetName="horLine" Property="Fill" Value="{StaticResource ListView.GridLine.Horizontal.MouseOver.Brush}"/>
<Setter Property="Foreground" Value="WhiteSmoke"/>
<Setter Property="FontSize" Value="20"/>
</Trigger>
<!--被选中-->
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="border" Property="Background" Value="#A145F8" />
<Setter Property="Foreground" Value="WhiteSmoke" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="Selector.IsSelectionActive" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="WhiteSmoke" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEnabled" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="border" Property="Opacity" Value="0.4" />
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource DefaultListViewHeader}">
<!--<GridView>-->
<GridViewColumn Width="360" Header="Name" DisplayMemberBinding="{Binding XPath=Name}"/>
<GridViewColumn Width="280" Header="Surname" DisplayMemberBinding="{Binding XPath=Surname}"/>
<GridViewColumn Width="150" Header="Age" DisplayMemberBinding="{Binding XPath=Age}"/>
</GridView>
</ListView.View>
</ListView>
<!--<ListView Margin="5" BorderThickness="1"
ItemsSource="{Binding Source={StaticResource People},XPath=/People/Person}">
<ListView.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Orange" Offset="0"/>
<GradientStop Color="Black" Offset="0.5"/>
<GradientStop Color="Orange" Offset="1"/>
</LinearGradientBrush>
</ListView.BorderBrush>
</ListView>-->
</StackPanel>
</Grid>
</Window>
CS
public class GridViewRowPresenterWithGridLines : GridViewRowPresenter
{
private static readonly Style DefaultSeparatorStyle;
public static readonly DependencyProperty SeparatorStyleProperty;
private readonly List<FrameworkElement> verticalLines = new List<FrameworkElement>();
static GridViewRowPresenterWithGridLines()
{
DefaultSeparatorStyle = new Style(typeof(Rectangle));
DefaultSeparatorStyle.Setters.Add(new Setter(Shape.FillProperty, SystemColors.ControlLightBrush));
SeparatorStyleProperty = DependencyProperty.Register(nameof(SeparatorStyle), typeof(Style), typeof(GridViewRowPresenterWithGridLines),
new UIPropertyMetadata(DefaultSeparatorStyle, SeparatorStyleChanged));
}
public Style SeparatorStyle
{
get { return (Style)GetValue(SeparatorStyleProperty); }
set { SetValue(SeparatorStyleProperty, value); }
}
public static readonly DependencyProperty GridLinesVisibilityProperty = DependencyProperty.Register(nameof(GridLinesVisibility), typeof(Visibility),
typeof(GridViewRowPresenterWithGridLines), new PropertyMetadata(Visibility.Collapsed));
public Visibility GridLinesVisibility
{
get { return (Visibility)GetValue(GridLinesVisibilityProperty); }
set { SetValue(GridLinesVisibilityProperty, value); }
}
public static readonly DependencyProperty GridLineWidthProperty = DependencyProperty.Register(nameof(GridLineWidth), typeof(double),
typeof(GridViewRowPresenterWithGridLines), new PropertyMetadata(1.0));
public double GridLineWidth
{
get { return (double)GetValue(GridLineWidthProperty); }
set { SetValue(GridLineWidthProperty, value); }
}
public static readonly DependencyProperty GridLineBrushProperty = DependencyProperty.Register(nameof(GridLineBrush), typeof(Brush),
typeof(GridViewRowPresenterWithGridLines), new PropertyMetadata(Brushes.Black));
public Brush GridLineBrush
{
get { return (Brush)GetValue(GridLineBrushProperty); }
set { SetValue(GridLineBrushProperty, value); }
}
private IEnumerable<FrameworkElement> Children
{
get { return LogicalTreeHelper.GetChildren(this).OfType<FrameworkElement>(); }
}
private static void SeparatorStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var presenter = (GridViewRowPresenterWithGridLines)d;
var style = (Style)e.NewValue;
foreach (FrameworkElement line in presenter.verticalLines)
{
line.Style = style;
}
}
protected override Size ArrangeOverride(Size arrangeSize)
{
var size = base.ArrangeOverride(arrangeSize);
var children = Children.ToList();
Visibility visible = (Visibility)(this.GetValue(GridLinesVisibilityProperty));
if (Visibility.Collapsed == visible)
{
return size;
}
EnsureLines(children.Count);
double width = (double)(this.GetValue(GridLineWidthProperty));
for (var i = 0; i < verticalLines.Count; i++)
{
var child = children[i];
if (i == verticalLines.Count - 1)
{
break;
}
//var x = child.TransformToAncestor(this).Transform(new Point(child.ActualWidth, 0)).X + child.Margin.Right;
var x = child.TransformToAncestor(this).Transform(new Point(child.ActualWidth, 0)).X + child.Margin.Right;
var rect = new Rect(x, -Margin.Top, width, size.Height + Margin.Top + Margin.Bottom);
var line = verticalLines[i];
line.Measure(rect.Size);
line.Arrange(rect);
}
return size;
}
private void EnsureLines(int count)
{
count = count - verticalLines.Count;
for (var i = 0; i < count; i++)
{
var line = (FrameworkElement)Activator.CreateInstance(SeparatorStyle.TargetType);
//line = new Rectangle { Fill = Brushes.Red };
line = new Rectangle { Fill = (Brush)(this.GetValue(GridLineBrushProperty)) };
line.Style = SeparatorStyle;
AddVisualChild(line);
verticalLines.Add(line);
}
}
protected override int VisualChildrenCount
{
get { return base.VisualChildrenCount + verticalLines.Count; }
}
protected override Visual GetVisualChild(int index)
{
var count = base.VisualChildrenCount;
return index < count ? base.GetVisualChild(index) : verticalLines[index - count];
}
}