我在我的Silverlight應用程序中有一個DataGrid,我想在該列進行排序時突出顯示整列。Silverlight Datagrid:當該列被排序時突出顯示整個列
它在概念上與前面的問題類似:Silverlight DataGrid: Highlight an entire column。
任何想法?我想過可能將一個行爲附加到LayoutUpdated事件並檢查單元格以查看它是否在排序列中?
我在我的Silverlight應用程序中有一個DataGrid,我想在該列進行排序時突出顯示整列。Silverlight Datagrid:當該列被排序時突出顯示整個列
它在概念上與前面的問題類似:Silverlight DataGrid: Highlight an entire column。
任何想法?我想過可能將一個行爲附加到LayoutUpdated事件並檢查單元格以查看它是否在排序列中?
有幾個問題需要解決,以便做你想做的事情。最大的問題是,找出列的排序時間應該會更困難。我發現唯一的方法是識別列被排序,使其DataGrid.ItemsSource
爲PagedCollectionView並在其SortDescriptions
屬性上偵聽CollectionChanged
事件。如果您的ItemsSource使用PagedCollectionView
,並且可以排序的所有列都是DataGridBoundColumn
(實際上是TemplateColumn以外的任何預構造),則此行爲應該與您想要執行的操作相當接近。
public class DataGridSortedColumnHighlightBehavior : Behavior<DataGrid>
{
private List<DataGridRow> rows = new List<DataGridRow>();
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.LoadingRow += AssociatedObject_LoadingRow;
AssociatedObject.UnloadingRow += AssociatedObject_UnloadingRow;
if (AssociatedObject.ItemsSource == null)
{
AssociatedObject.LayoutUpdated += AssociatedObject_LayoutUpdated;
}
else
{
var collection =
((AssociatedObject.ItemsSource as PagedCollectionView).SortDescriptions as INotifyCollectionChanged);
collection.CollectionChanged += DataGridSortedColumnHighlightBehavior_CollectionChanged;
}
}
void AssociatedObject_UnloadingRow(object sender, DataGridRowEventArgs e)
{
rows.Remove(e.Row);
}
void AssociatedObject_LoadingRow(object sender, DataGridRowEventArgs e)
{
rows.Add(e.Row);
}
private void AssociatedObject_LayoutUpdated(object sender, EventArgs e)
{
if (AssociatedObject.ItemsSource != null)
{
AssociatedObject.LayoutUpdated -= AssociatedObject_LayoutUpdated;
var collection =
((AssociatedObject.ItemsSource as PagedCollectionView).SortDescriptions as INotifyCollectionChanged);
collection.CollectionChanged += DataGridSortedColumnHighlightBehavior_CollectionChanged;
}
}
void DataGridSortedColumnHighlightBehavior_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if(e.NewItems != null)
{
foreach(SortDescription sortDesc in e.NewItems)
{
foreach(var column in AssociatedObject.Columns)
{
var boundColumn = column as DataGridBoundColumn;
if (boundColumn == null)
continue;
if (boundColumn.Binding.Path.Path == sortDesc.PropertyName)
{
foreach (var row in rows)
ColorCell(column,row,Colors.Red);
}
}
}
}
if(e.OldItems != null)
{
foreach(SortDescription sortDesc in e.OldItems)
{
foreach(var column in AssociatedObject.Columns)
{
var boundColumn = column as DataGridBoundColumn;
if (boundColumn == null)
continue;
if (boundColumn.Binding.Path.Path == sortDesc.PropertyName)
{
foreach (var row in rows)
ColorCell(column,row,Colors.White);
}
}
}
}
}
private void ColorCell(DataGridColumn column, DataGridRow item, Color color)
{
var content = column.GetCellContent(item);
if (content == null)
return;
var parent = GetParent<DataGridCell>(content);
if (parent != null)
parent.Background = new SolidColorBrush(color);
}
public static T GetParent<T>(DependencyObject source)
where T : DependencyObject
{
DependencyObject parent = VisualTreeHelper.GetParent(source);
while (parent != null && !typeof(T).IsAssignableFrom(parent.GetType()))
{
parent = VisualTreeHelper.GetParent(parent);
}
return (T)parent;
}
}
那近乎完美的作品。非常感謝您的回答,我注意到的唯一一件事情是它有時會出現滾動問題,但它仍然是一個非常大的幫助! – GotDibbs 2010-10-19 18:49:29
滾動問題是由'DataGrid'虛擬化行的方式引起的。它只是實例化屏幕上可見的行數加1並將其保存在內存中。要解決此問題,您可能需要修改代碼以保留已排序的列的列表,並在加載行事件處理程序中突出顯示這些列的單元格。 – Stephan 2010-10-19 19:02:10
Yeap這是我採取的確切路線。再次感謝! – GotDibbs 2010-10-19 19:20:33