问题描述
我正在使用这样的标准.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中设置固定列,我想即时生成它们。但是,如果我试图将列绑定到任何我收到错误,说
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列绑定到代码后面?
Is there a way to dynamically bind the DataGrid columns to something in code behind?
推荐答案
是的,列属性是ReadOnly,所以我们不能直接绑定到它。如果要绑定列,那么您可以尝试使用绑定到的附加属性,从而更新列。
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的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!