简体   繁体   English

prism / mvvm:将列绑定到DataGrid

[英]prism/mvvm: binding Columns to DataGrid

I'm using a standard .NET DataGrid like this: 我正在使用这样的标准.NET DataGrid:

<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>

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. 现在我想在ViewModel中定义列,而不是在xaml中设置固定列,我想在运行中生成它们。 However, if I try to bind the Columns to anything I get an error, saying 但是,如果我尝试将列绑定到任何东西,我会收到错误,说

DataGrid.Columns is a readonly property and can't be bound. DataGrid.Columns是一个只读属性,无法绑定。

Is there a way to dynamically bind the DataGrid columns to something in code behind? 有没有办法动态地将DataGrid列绑定到后面的代码中?

Yes, the Columns Property is ReadOnly so we can't bind to it directly. 是的,Columns属性是ReadOnly,因此我们无法直接绑定它。 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. 如果要绑定列,则可以尝试使用绑定的附加属性,然后更新列。

Update 更新
Using delta of changes in the CollectionChanged event. 在CollectionChanged事件中使用delta更改。

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

Then you can bind the BindableColumns property to your ColumnsCollection 然后,您可以将BindableColumns属性绑定到ColumnsCollection

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM