C# 如何使用WPF绑定触发DataGrid中特定单元格的更新
我有一个自定义类,提供具有C# 如何使用WPF绑定触发DataGrid中特定单元格的更新,c#,wpf,binding,C#,Wpf,Binding,我有一个自定义类,提供具有只读属性的三维点信息: public class Point3d { private readonly double x; public double X { get { return x; } } private readonly double y; public double Y { get { return y; } } private readonly double z; public double Z { g
只读属性的三维点信息:
public class Point3d
{
private readonly double x;
public double X { get { return x; } }
private readonly double y;
public double Y { get { return y; } }
private readonly double z;
public double Z { get { return z; } }
public PoseCartesian(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
要显示多个3d点,我使用WPF中有四列的DataGrid
。第一列应该显示条目的行号
<DataGrid Name="dgrPoints" AutoGenerateColumns="False"
ItemsSource="{Binding UpdateSourceTrigger=Default, Mode=OneWay}"
SelectionChanged="dgr_Poses_SelectionChanged" CanUserSortColumns="False"
IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn x:Name="colI" Binding="{Binding Mode=OneWay,
RelativeSource={RelativeSource AncestorType=DataGridRow},
Converter={local:RowToIndexConverter}}"/>
<DataGridTextColumn x:Name="colX" Binding="{Binding X}" Header="X"/>
<DataGridTextColumn x:Name="colY" Binding="{Binding Y}" Header="Y"/>
<DataGridTextColumn x:Name="colZ" Binding="{Binding Z}" Header="Z"/>
</DataGrid.Columns>
</DataGrid>
通过设置DataContext
结束绑定:
this.pointList = new ObservableCollection<Point3d>();
dgrPoints.ItemsSource= this.poseList;
无论何时添加新行(Point3d
),这一切都可以正常工作,并在DataGrid
的第一列中设置相应的行号。但每当删除一行时,行号都不会更新,因为转换器是通过添加新的DataGridRow
触发的。现在,我通过将DataGrid.DataContext
设置为null
并再次添加来强制取消更新:
this.pointList.RemoveAt(0);
dgrPoints.ItemsSource = null;
dgrPoints.ItemsSource = this.pointList;
这不是实现行号不更新的正确解决方案。每当点列表更改时,触发每行转换器的最佳方法是什么
我不想使用DataGridRow.Header
属性,因为这会替换我的列。如果我错了,请纠正我。除此之外,每个考虑不同方法的建议都是受欢迎的。您可以处理加载行
和ItemContainerGenerator.ItemsChanged
事件,并将DataGridRow
容器的标记
属性设置为相应的行号:
public Window1()
{
InitializeComponent();
dgrPoints.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
dgrPoints.LoadingRow += DgrPoints_LoadingRow;
dgrPoints.ItemsSource = ...;
}
private void DgrPoints_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Tag = (e.Row.GetIndex() + 1).ToString();
}
private void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e)
{
IEnumerable<DataGridRow> rows = FindVisualChildren<DataGridRow>(dgrPoints);
foreach (DataGridRow row in rows)
row.Tag = (row.GetIndex() + 1).ToString();
}
private static IEnumerable<T> FindVisualChildren<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
公共窗口1()
{
初始化组件();
dgrPoints.ItemContainerGenerator.ItemsChanged+=ItemContainerGenerator\u ItemsChanged;
dgrPoints.LoadingRow+=dgrPoints_LoadingRow;
dgrPoints.ItemsSource=。。。;
}
私有void DgrPoints_LoadingRow(对象发送方,DataGridRowEventArgs e)
{
e、 Row.Tag=(e.Row.GetIndex()+1.ToString();
}
私有void ItemContainerGenerator_ItemsChanged(对象发送方,ItemsChangedEventArgs e)
{
IEnumerable rows=FindVisualChildren(dgrPoints);
foreach(DataGridRow行中的行)
row.Tag=(row.GetIndex()+1.ToString();
}
私有静态IEnumerable FindVisualChildren(DependencyObject DependencyObject),其中T:DependencyObject
{
if(dependencyObject!=null)
{
for(int i=0;i
this.pointList.RemoveAt(0);
dgrPoints.ItemsSource = null;
dgrPoints.ItemsSource = this.pointList;
public Window1()
{
InitializeComponent();
dgrPoints.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
dgrPoints.LoadingRow += DgrPoints_LoadingRow;
dgrPoints.ItemsSource = ...;
}
private void DgrPoints_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Tag = (e.Row.GetIndex() + 1).ToString();
}
private void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e)
{
IEnumerable<DataGridRow> rows = FindVisualChildren<DataGridRow>(dgrPoints);
foreach (DataGridRow row in rows)
row.Tag = (row.GetIndex() + 1).ToString();
}
private static IEnumerable<T> FindVisualChildren<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
<DataGrid Name="dgrPoints" AutoGenerateColumns="False"
ItemsSource="{Binding UpdateSourceTrigger=Default, Mode=OneWay}"
CanUserSortColumns="False"
IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn x:Name="colI" Binding="{Binding Path=Tag, Mode=OneWay,
RelativeSource={RelativeSource AncestorType=DataGridRow}}"/>
<DataGridTextColumn x:Name="colX" Binding="{Binding X}" Header="X"/>
<DataGridTextColumn x:Name="colY" Binding="{Binding Y}" Header="Y"/>
<DataGridTextColumn x:Name="colZ" Binding="{Binding Z}" Header="Z"/>
</DataGrid.Columns>
</DataGrid>