Prism/mvvm:将列绑定到 DataGrid [英] prism/mvvm: binding Columns to DataGrid

查看:40
本文介绍了Prism/mvvm:将列绑定到 DataGrid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用这样的标准 .NET DataGrid:

I'm using a standard .NET DataGrid like this:

<DataGrid ItemsSource="{Binding Datensaetze}" AutoGenerateColumns="False">
 <DataGrid.Columns>
   <DataGridTextColumn Header="my col 1" Binding="{Binding MyCol1}"/>
   <DataGridTextColumn Header="my col 2" Binding="{Binding MyCol2}"/>
   <DataGridTextColumn Header="my col 3" Binding="{Binding MyCol3}"/>
 </DataGrid.Columns>
</DataGrid>

这很好用.现在我想在 ViewModel 中定义列,而不是在 xaml 中设置固定列,我想动态生成它们.但是,如果我尝试将 Columns 绑定到任何内容,我会收到一个错误,说

This is working nicely. Now I want to define the columns in the ViewModel, and instead of setting fixed columns in xaml I want to generate them on the fly. However, if I try to bind the Columns to anything I get an error, saying

DataGrid.Columns 是只读属性,无法绑定.

DataGrid.Columns is a readonly property and can't be bound.

有没有办法将 DataGrid 列动态绑定到后面的代码中?

Is there a way to dynamically bind the DataGrid columns to something in code behind?

推荐答案

是的,Columns 属性是只读的,所以我们不能直接绑定到它.如果您想绑定列,那么您可以尝试使用绑定到的附加属性,从而更新列.

Yes, the Columns Property is ReadOnly so we can't bind to it directly. If you want to Bind Columns then you can try to use an attached property which you bind to, which in turn updates the Columns.

更新
在 CollectionChanged 事件中使用变化增量.

Update
Using delta of changes in the CollectionChanged event.

public class DataGridColumnsBehavior
{
    public static readonly DependencyProperty BindableColumnsProperty =
        DependencyProperty.RegisterAttached("BindableColumns",
                                            typeof(ObservableCollection<DataGridColumn>),
                                            typeof(DataGridColumnsBehavior),
                                            new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
    private static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        DataGrid dataGrid = source as DataGrid;
        ObservableCollection<DataGridColumn> columns = e.NewValue as ObservableCollection<DataGridColumn>;
        dataGrid.Columns.Clear();
        if (columns == null)
        {
            return;
        }
        foreach (DataGridColumn column in columns)
        {
            dataGrid.Columns.Add(column);
        }
        columns.CollectionChanged += (sender, e2) =>
        {
            NotifyCollectionChangedEventArgs ne = e2 as NotifyCollectionChangedEventArgs;
            if (ne.Action == NotifyCollectionChangedAction.Reset)
            {
                dataGrid.Columns.Clear();
                foreach (DataGridColumn column in ne.NewItems)
                {
                    dataGrid.Columns.Add(column);
                }
            }
            else if (ne.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (DataGridColumn column in ne.NewItems)
                {
                    dataGrid.Columns.Add(column);
                }
            }
            else if (ne.Action == NotifyCollectionChangedAction.Move)
            {
                dataGrid.Columns.Move(ne.OldStartingIndex, ne.NewStartingIndex);
            }
            else if (ne.Action == NotifyCollectionChangedAction.Remove)
            {
                foreach (DataGridColumn column in ne.OldItems)
                {
                    dataGrid.Columns.Remove(column);
                }
            }
            else if (ne.Action == NotifyCollectionChangedAction.Replace)
            {
                dataGrid.Columns[ne.NewStartingIndex] = ne.NewItems[0] as DataGridColumn;
            }
        };
    }
    public static void SetBindableColumns(DependencyObject element, ObservableCollection<DataGridColumn> value)
    {
        element.SetValue(BindableColumnsProperty, value);
    }
    public static ObservableCollection<DataGridColumn> GetBindableColumns(DependencyObject element)
    {
        return (ObservableCollection<DataGridColumn>)element.GetValue(BindableColumnsProperty);
    }
}

然后您可以将 BindableColumns 属性绑定到您的 ColumnsCollection

Then you can bind the BindableColumns property to your ColumnsCollection

<DataGrid AutoGenerateColumns="False"
          local:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection}">
    <!-- ... -->
</DataGrid>

这篇关于Prism/mvvm:将列绑定到 DataGrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆