在WPF数据网格中排序事件后,依赖属性不起作用
本文关键字:依赖 属性 不起作用 事件 排序 数据 WPF 数据网 网格 | 更新日期: 2023-09-27 17:49:38
我有一个WPF数据网格,它有一个依赖属性。我使用MVVM和WPF数据网格绑定到一个可观察集合。网格保存搜索结果。当单击搜索按钮时,我从数据库中检索数据,填充可观察集合,然后填充网格。所有的好!在'search button click'方法的最后一行,我将依赖属性更新为true,这将触发依赖属性。依赖属性类中的代码将格式化数据网格(比如在某些单元格上设置边框,并确保重复的数据只显示一次)。
当一个业务需求是能够通过单击列标题进行排序时,我的问题就开始了。使用wpf数据网格的默认排序会导致网格失去格式,因此我创建了自己的排序处理程序,并在最后设置e.handled = true来禁用wpf数据网格控件的默认排序。还是很好!
问题现在出现了。如果我通过单击搜索按钮进行新的搜索,网格中的结果将被显示,但没有被格式化!我在依赖代码中设置了一个断点,发现在这个实例中断点没有被击中。
所以我的问题是……排序中的代码(我在下面包括)是否以某种方式破坏了依赖属性与数据网格的绑定?我想提请您注意我清除集合并重新填充它的代码。我是否应该以不同的方式实现排序,以避免出现这种行为?排序处理程序中的代码。
void fg_Sorting(object sender, DataGridSortingEventArgs e) {
System.Windows.Controls.DataGrid dg = sender as System.Windows.Controls.DataGrid;
if (dg == null) {
return;
}
DataGridMergeCellBehavior.SetIsMerged(dg, false);
ObservableCollection<AssetPPM2GridEntity> source = dg.ItemsSource as ObservableCollection<AssetPPM2GridEntity>;
List<AssetPPM2GridEntity> myList = source.OrderBy(x => x.Property).ToList();
source.Clear();
foreach (var item in myList) {
source.Add(item);
}
// This property below is the dependency property which formats the grid.
DataGridMergeCellBehavior.SetIsMerged(dg, true);
e.Handled = true;
}
如果你需要更多的信息,请告诉我。我只是从你的经验中寻找可能解释这种行为的原因,我可以进一步调查。
下面是依赖属性的代码。
public class DataGridMergeCellBehavior : DependencyObject
{
private static bool inUse = false;
public static readonly System.Windows.DependencyProperty IsMergedProperty = System.Windows.DependencyProperty.RegisterAttached("IsMerged", typeof(bool), typeof(DataGridMergeCellBehavior), new PropertyMetadata(false, IsMergedChanged));
public static bool GetIsMerged(DataGrid grid) {
return (bool)grid.GetValue(IsMergedProperty);
}
public static void SetIsMerged(DataGrid grid, bool value) {
grid.SetValue(IsMergedProperty, value);
}
private static void dg_ScrollChanged(object sender, ScrollChangedEventArgs e) {
if (e.VerticalChange != 0 && !inUse) {
inUse = true;
DataGrid dataGrid = sender as DataGrid;
int visibleRows = 0;
int firstVisibleRowIndex = 0;
foreach (var Item in dataGrid.Items) {
var Row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(Item);
if (Row != null && Row.IsVisible) {
if (visibleRows == 0) {
firstVisibleRowIndex = Convert.ToInt32(Math.Floor(e.VerticalOffset));
}
visibleRows++;
}
}
MergeDataGrid(dataGrid, visibleRows, firstVisibleRowIndex);
inUse = false;
}
}
private static void IsMergedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
DataGrid dg = obj as DataGrid;
if (dg != null) {
int rowCount = dg.Items.Count;
if (rowCount > 100) {
rowCount = 100; // Why process the entire grid when not more than 100 will be shown to the user.
}
if (dg.Columns.Count > 0 && (bool)e.NewValue) {
dg.UpdateLayout();
MergeDataGrid(dg, rowCount, 0);
}
else {
if (dg.Columns.Count == 0) {
dg.Loaded += AssociatedObjectLoaded;
//dg.LoadingRow += OnLoadingRow;
//dg.UnloadingRow += OnUnloadingRow;
//dg.MouseLeftButtonDown += AssociatedObjectMouseLeftButtonUp;
}
MergeDataGrid(dg, rowCount, 0);
}
}
}
static void AssociatedObjectLoaded(object sender, RoutedEventArgs e) {
DataGrid grid = sender as DataGrid;
grid.RemoveHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(dg_ScrollChanged));
grid.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(dg_ScrollChanged));
}
private static void MergeDataGrid(DataGrid grid, int visibleRows, int firstVisibleRowIndex) {
// Code which will format cells with borders and delete cell content if its the same.
}
这是我的数据网格XAML。
<DataGrid TabIndex="8" x:Name="fg" Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="4" Margin="5" RowHeaderWidth="0" ContextMenu="{StaticResource menuContext}"
ItemsSource="{Binding AssetPPM2GridEntityCollection}" ColumnHeaderStyle="{StaticResource ColumnContextMenus}" HeadersVisibility="{Binding HeaderVisibility}"
SelectedIndex="{Binding GrdFgSelectedIndex}" AutoGenerateColumns="False" SelectionUnit="FullRow" SelectionMode="Extended"
EnableRowVirtualization="True" EnableColumnVirtualization="False" RowBackground="PapayaWhip"
VirtualizingPanel.VirtualizationMode="Standard" CanUserReorderColumns="False"
CanUserAddRows="False" GridLinesVisibility="Vertical" CanUserSortColumns="True" CanUserResizeColumns="False"
dp:DataGridMergeCellBehavior.IsMerged="{Binding Source={StaticResource assetPPM2ViewModel}, Path=IsMergeCellsChecked, UpdateSourceTrigger=PropertyChanged}"
PreviewMouseWheel="fg_PreviewMouseWheel" >
排序处理程序驻留在视图后面的代码中。
感谢大家的评论。我张贴的答案,如果有人应该偶然发现这个或类似的问题。
问题是由这行代码引起的。
// This property below is the dependency property which formats the grid.
DataGridMergeCellBehavior.SetIsMerged(dg, true);
直接设置依赖属性导致不一致的行为。我仍然不知道这背后的确切技术原因。
解决方案是获得ViewModel的实例,然后设置绑定到依赖属性的ViewModel的属性(为TRUE)。