在学习DataGrid的过程中,发现自定义DataGridColumnheader 会非常必要,而且可以自定以column 模板。
本例子主要是自定义了Column Header, 自定义Column 内容显示,可以对Column Header的排序和通过拖动header修改column的宽度.
1. 在xml 中添加如下资源
a. 带有箭头的datatemplate, 为用户点Header排序的时候可以显示不同的箭头
向上的箭头data template:
向下的箭头 data template:
首先为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
Man
Female
增加employee 信息, 在.cs文件中增加类
public class EmployeeCollection : ObservableCollection
c.添加header的style
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
{
///
/// Interaction logic for GridDragDropManual.xaml
///
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();
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
{
}
public class EmployeeCollection : ObservableCollection
{
}
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";
}
}