WPF DataGrid的Converter获得每行的数据
前端写法
获得每行的数据类对象
,比如Employee
<Path Data="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGridRow}, Converter={StaticResource MmsDataToPathConverter}}" />
获得DataGridRow
<Path Data="{Binding ., RelativeSource={RelativeSource AncestorType=DataGridRow}, Converter={StaticResource MmsDataToPathConverter}}" />
后端写法
/// <summary>
/// 设置操作列
/// </summary>
/// <param name="input"></param>
private void SetOperations()
{
DataGridTemplateColumn dataGridTemplateColumn = new DataGridTemplateColumn();
dataGridTemplateColumn.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
dataGridTemplateColumn.Header = "操作";
FrameworkElementFactory gridFactory = new FrameworkElementFactory(typeof(Grid));
//修改按钮
AddButton(gridFactory, 0, "修改", ModifyData, new ModifyVisibilityConverter());
//删除按钮
AddButton(gridFactory, 1, "删除", DeleteData, new DeleteVisibilityConverter());
DataTemplate cellTemplate1 = new DataTemplate();
cellTemplate1.VisualTree = gridFactory;
dataGridTemplateColumn.CellTemplate = cellTemplate1;
dataGrid.Columns.Add(dataGridTemplateColumn);
}
private static void AddButton(FrameworkElementFactory gridFactory, int i, string content, RoutedEventHandler routedEventHandler, IValueConverter valueConverter)
{
FrameworkElementFactory col1 = new FrameworkElementFactory(typeof(ColumnDefinition));
col1.SetValue(ColumnDefinition.WidthProperty, new GridLength(1, GridUnitType.Star));
gridFactory.AppendChild(col1);
//https://stackoverflow.com/questions/47401286/how-to-pro-gramatically-add-click-event-to-frameworkelementfactory
FrameworkElementFactory btn1Factory = new FrameworkElementFactory(typeof(Button));
btn1Factory.SetValue(Button.ContentProperty, content);
btn1Factory.AddHandler(Button.ClickEvent, routedEventHandler);
//绑定数据源
var bind = new Binding("DataContext");
//绑定每一行的数据
//https://stackoverflow.com/questions/39873228/how-to-bind-to-wpf-datagrid-row-class-instance-and-not-its-property
bind.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor) { AncestorType = typeof(DataGridRow) };
//设置成自定义Converter
bind.Converter = valueConverter;
//判断该按钮是否应该存在
btn1Factory.SetBinding(Button.VisibilityProperty, bind);
btn1Factory.SetValue(Grid.ColumnProperty, i);
gridFactory.AppendChild(btn1Factory);
}
在Converter中获得数据
public class DeleteVisibilityConverter : IValueConverter
{
//当值从绑定源传播给绑定目标时,调用方法Convert
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var data = value as FakeDatabase;
if (data.Id % 2 == 0)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
//当值从绑定目标传播给绑定源时,调用此方法ConvertBack
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new Exception("");
}
}
效果是单行只有删除按钮,双行只有修改按钮
示例代码
参考资料
How to bind to WPF DataGrid row class instance and not it's property?
学习技术最好的文档就是【官方文档】,没有之一。
还有学习资料【Microsoft Learn】、【CSharp Learn】、【My Note】。
如果,你认为阅读这篇博客让你有些收获,不妨点击一下右下角的【推荐】按钮。
如果,你希望更容易地发现我的新博客,不妨点击一下【关注】。