DataGrid 自定义DataGridColumnheader

2016-12-02 19:52:40来源:CSDN作者:SpringDou人点击

在学习DataGrid的过程中,发现自定义DataGridColumnheader 会非常必要,而且可以自定以column 模板。

本例子主要是自定义了Column Header, 自定义Column 内容显示,可以对Column Header的排序和通过拖动header修改column的宽度.

1. 在xml 中添加如下资源

a. 带有箭头的datatemplate, 为用户点Header排序的时候可以显示不同的箭头

向上的箭头data template:                         

            <DataTemplate x:Key="ColumHeaderArrowUp">                <DockPanel>                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding}"></TextBlock>                    <Path x:Name="PT" Stroke="Gray" Fill="SeaGreen" RenderTransformOrigin="0.5,.5">                        <Path.RenderTransform>                            <RotateTransform x:Name="RT" Angle="0"></RotateTransform>                        </Path.RenderTransform>                        <Path.Data>                            <PathGeometry>                                <PathFigure StartPoint="3.5,3">                                    <LineSegment Point="0,9"></LineSegment>                                    <LineSegment Point="7,9"></LineSegment>                                    <LineSegment Point="3.5,3"></LineSegment>                                </PathFigure>                            </PathGeometry>                        </Path.Data>                    </Path>                </DockPanel>            </DataTemplate>
      向下的箭头 data template:

            <DataTemplate x:Key="ColumHeaderArrowDown">                <DockPanel>                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding}"></TextBlock>                    <Path x:Name="PT" Stroke="Gray" Fill="SeaGreen" RenderTransformOrigin="0.5,0.5">                        <Path.RenderTransform>                            <RotateTransform x:Name="RT" Angle="180"></RotateTransform>                        </Path.RenderTransform>                        <Path.Data>                            <PathGeometry>                                <PathFigure StartPoint="3.5,3">                                    <LineSegment Point="0,9"></LineSegment>                                    <LineSegment Point="7,9"></LineSegment>                                    <LineSegment Point="3.5,3"></LineSegment>                                </PathFigure>                            </PathGeometry>                        </Path.Data>                    </Path>                </DockPanel>            </DataTemplate>

b. 添加数据资源

                  首先为XML增加如下namespace:

             xmlns:Local="clr-namespace:ImageVideoPlayer"             xmlns:sys="clr-namespace:System;assembly=mscorlib"             xmlns:sysModel="clr-namespace:System.ComponentModel;assembly=System"

                  增加性别资源, 需要在.cs文件中增加类   public class GenderCollection:ObservableCollection<string>{}

            <Local:GenderCollection x:Key="gendercollection">                <sys:String>Man</sys:String>                <sys:String>Female</sys:String>            </Local:GenderCollection>
  增加employee 信息, 在.cs文件中增加类    public class EmployeeCollection : ObservableCollection<Employee>{}

            <Local:EmployeeCollection x:Key="employeecollection">                <Local:Employee FirstName="A1" LastName="Micheal" bValid="True" Gender="Man" Number="1"></Local:Employee>                <Local:Employee FirstName="A2" LastName="Micheal" bValid="True" Gender="Man" Number="2"></Local:Employee>                <Local:Employee FirstName="A3" LastName="Micheal" bValid="True" Gender="Female" Number="3"></Local:Employee>                <Local:Employee FirstName="A4" LastName="Micheal" bValid="True" Gender="Female" Number="4"></Local:Employee>            </Local:EmployeeCollection>
                   

c.添加header的style

            <Style TargetType="DataGridColumnHeader" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">                <Setter Property="Template">                    <Setter.Value>                        <ControlTemplate>                            <Button Height="auto" Content="{Binding}" x:Name="Btn" Width="auto" Click="Btn_Click" MouseEnter="Btn_MouseEnter" MouseLeave="Btn_MouseLeave" MouseMove="Btn_MouseMove" PreviewMouseDown="Btn_PreviewMouseDown">                            </Button>                            <ControlTemplate.Triggers>                                <Trigger Property="DataGridColumnHeader.SortDirection" Value="0">                                    <Setter Property="Button.ContentTemplate" TargetName="Btn" Value="{DynamicResource ColumHeaderArrowUp}"></Setter>                                </Trigger>                                <Trigger Property="DataGridColumnHeader.SortDirection" Value="1">                                    <Setter Property="Button.ContentTemplate" TargetName="Btn" Value="{DynamicResource ColumHeaderArrowDown}"></Setter>                                </Trigger>                            </ControlTemplate.Triggers>                        </ControlTemplate>                    </Setter.Value>                </Setter>                <EventSetter Event="Click" Handler="HeaderClickRoutedEventHandler"></EventSetter>                <EventSetter Event="DragOver" Handler="HeaderDragOverEventHandler"></EventSetter>                <EventSetter Event="Drop" Handler="HeaderDragDropEventHandler"></EventSetter>                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="HeaderMouseButtonEventHandler"></EventSetter>            </Style>

d. 添加DataGrid

        <DataGrid x:Name="EmployeeGrid" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" ItemsSource="{StaticResource employeecollection}" AutoGenerateColumns="False" AlternationCount="2"                  MinColumnWidth="20" CanUserAddRows="False" CanUserResizeRows="False" CanUserSortColumns="True" SelectionUnit="FullRow" AllowDrop="True" SelectionMode="Single" CanUserReorderColumns="True" RowDetailsVisibilityMode="VisibleWhenSelected">            <DataGrid.Columns>                <DataGridTextColumn Header="Number" Binding="{Binding Number}"></DataGridTextColumn>                <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"></DataGridTextColumn>                <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"></DataGridTextColumn>                <DataGridTemplateColumn Header="Gender" SortMemberPath="{Binding Gender}">                    <DataGridTemplateColumn.CellTemplate>                        <DataTemplate>                            <StackPanel>                                <TextBlock Text="{Binding Gender}"></TextBlock>                            </StackPanel>                        </DataTemplate>                    </DataGridTemplateColumn.CellTemplate>                    <DataGridTemplateColumn.CellEditingTemplate>                        <DataTemplate>                            <StackPanel>                                <ComboBox ItemsSource="{StaticResource gendercollection}" SelectedItem="{Binding Gender}"></ComboBox>                            </StackPanel>                        </DataTemplate>                    </DataGridTemplateColumn.CellEditingTemplate>                </DataGridTemplateColumn>                <DataGridCheckBoxColumn Header="Valid" Binding="{Binding bValid}">                </DataGridCheckBoxColumn>            </DataGrid.Columns>        </DataGrid>

2. 在.cs文件中内容

using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Controls.Primitives;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace ImageVideoPlayer{    /// <summary>    /// Interaction logic for GridDragDropManual.xaml    /// </summary>    public partial class GridDragDropManual : UserControl    {        public GridDragDropManual()        {            InitializeComponent();        }        #region helper        public void SortColumn(string header, bool bAescending)        {            var employees = this.grid.Resources["employeecollection"] as EmployeeCollection;            var tempList = new List<Employee>();            tempList.AddRange(employees);            tempList.Sort((x, y) =>            {                var tempX = x;                var tempY = y;                if(bAescending)                {                    tempX = y;                    tempY = x;                }                if (header.Contains("First"))                    return tempX.FirstName.CompareTo(tempY.FirstName);                else if (header.Contains("Last"))                    return tempX.LastName.CompareTo(tempY.LastName);                else if (header.Contains("Number"))                    return tempX.Number.CompareTo(tempY.Number);                else if (header.Contains("Gender"))                    return tempX.Gender.CompareTo(tempY.Gender);                else if(header.Contains("Valid"))                    return tempX.bValid.CompareTo(tempY.bValid);                return 0;            });            employees.Clear();            foreach(var tmp in tempList)            {                employees.Add(tmp);            }        }        void ClearSort()        {            foreach (var clm in this.EmployeeGrid.Columns)            {                //clm.HeaderTemplate = null;                clm.SortDirection = null;            }        }        #endregion        #region event        public static readonly DependencyProperty DPbUp = DependencyProperty.Register("bUp", typeof(bool), typeof(GridDragDropManual));        bool _bUp = true;        bool bUp         {             get { return (bool)GetValue(DPbUp); }             set { SetValue(DPbUp,value); }         }        bool bColumnResize = false;        int ResizeIndex;        void HeaderClickRoutedEventHandler(object sender, System.Windows.RoutedEventArgs e)        {            if (bColumnResize) return;            var header = sender as DataGridColumnHeader;            if (header == null) return;                        SortColumn(header.Content as string, bUp);            bUp = !bUp;            _bUp = bUp;            ClearSort();            header.Column.SortDirection = bUp ? ListSortDirection.Ascending : ListSortDirection.Descending;            this.EmployeeGrid.CurrentColumn = header.Column;        }        private void HeaderDragOverEventHandler(object sender, System.Windows.DragEventArgs e)        {        }        private void HeaderDragDropEventHandler(object sender, System.Windows.DragEventArgs e)        {        }                private void HeaderMouseButtonEventHandler(object sender, System.Windows.Input.MouseButtonEventArgs e)        {        }        #endregion        private void Btn_Click(object sender, RoutedEventArgs e)        {        }        private void Btn_MouseEnter(object sender, MouseEventArgs e)        {        }                private void Btn_MouseLeave(object sender, MouseEventArgs e)        {            if (bColumnResize)            {                Cursor = Cursors.Arrow;                bColumnResize = false;            }        }        Point oldPos;        private void Btn_MouseMove(object sender, MouseEventArgs e)        {            var btn = sender as Button;            if (btn == null) return;            var pos = e.GetPosition(btn);            var rect = VisualTreeHelper.GetDescendantBounds(btn);            var parent = VisualTreeHelper.GetParent(btn);            while(parent != null)            {                if(parent is DataGridColumnHeader)                {                    break;                }                parent = VisualTreeHelper.GetParent(parent);            }            if(parent == null)                return;            var header = parent as DataGridColumnHeader;                        if (e.LeftButton == MouseButtonState.Pressed)            {                if (bColumnResize && header.Column.DisplayIndex == ResizeIndex)                {                    header.Column.Width = new DataGridLength(header.Column.ActualWidth + pos.X - oldPos.X);                    oldPos = pos;                }                else                    bColumnResize = false;            }            else            {                oldPos = pos;                rect.Inflate(0, -3);                bool bDragArea = false;                if (rect.Contains(pos))                {                    if ((rect.Right - pos.X) < 10)                    {                        bDragArea = true;                    }                }                if (bDragArea)                {                    Cursor = Cursors.SizeWE;                    if (!bColumnResize)                    {                        bColumnResize = true;                        ResizeIndex = header.Column.DisplayIndex;                    }                }                else                    bColumnResize = false;            }            if (!bColumnResize)            {                Cursor = Cursors.Arrow;                ResizeIndex = -1;            }        }        private void Btn_PreviewMouseDown(object sender, MouseButtonEventArgs e)        {            if (bColumnResize)                e.Handled = true;            if(bColumnResize)            {                var btn = sender as Button;                oldPos = e.GetPosition(btn);            }        }    }    public class GenderCollection:ObservableCollection<string>    {    }    public class EmployeeCollection : ObservableCollection<Employee>    {    }    public class Employee    {        public string FirstName { get; set; }        public string LastName { get; set; }        public int Number { get; set; }        public string Gender { get; set; }        public bool bValid { get; set; }        public Employee()        {            bValid = true;            Gender = "Man";        }    }





      



最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台