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("");
    }
}

效果是單行只有刪除按鈕,雙行只有修改按鈕

示例代碼

Converters

參考資料

How to bind to WPF DataGrid row class instance and not it's property?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM