所以,我必须构建一个UserControl
来保存DataGrid
。 Row
的每个DataGrid
都会有另一个DataGrid
,分别保存行的详细信息。
最初,我遇到一些问题,要将Columns
从DataGrids
绑定到来电者UserControl
,因为Columns
不是DP,然后我用附属物。
所以这就是样本的样子。
MainWindow.xaml
<Grid>
<local:CustomDataGrid >
<local:CustomDataGrid.Columns>
<DataGridTextColumn Header="Emp Name" Binding="{Binding Name}" />
</local:CustomDataGrid.Columns>
<local:CustomDataGrid.RowDetailColumns>
<DataGridTextColumn Header="Manager Name" Binding="{Binding ManagerName}" />
</local:CustomDataGrid.RowDetailColumns>
</local:CustomDataGrid>
</Grid>
MainWindow.xaml.cs
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var emps = new List<Employee>();
emps.Add(new Employee() { ID = 1, Name = "aaa", Details = new List<Manager>() { new Manager() { ManagerID = 11, ManagerName = "Maaa" }, new Manager() { ManagerID = 22, ManagerName = "Mbbb" }, new Manager() { ManagerID = 33, ManagerName = "Mccc" } } });
emps.Add(new Employee() { ID = 1, Name = "aaa", Details = new List<Manager>() { new Manager() { ManagerID = 11, ManagerName = "Maaa" }, new Manager() { ManagerID = 22, ManagerName = "Mbbb" }, new Manager() { ManagerID = 33, ManagerName = "Mccc" } } });
emps.Add(new Employee() { ID = 1, Name = "aaa", Details = new List<Manager>() { new Manager() { ManagerID = 11, ManagerName = "Maaa" }, new Manager() { ManagerID = 22, ManagerName = "Mbbb" }, new Manager() { ManagerID = 33, ManagerName = "Mccc" } } });
emps.Add(new Employee() { ID = 1, Name = "aaa", Details = new List<Manager>() { new Manager() { ManagerID = 11, ManagerName = "Maaa" }, new Manager() { ManagerID = 22, ManagerName = "Mbbb" }, new Manager() { ManagerID = 33, ManagerName = "Mccc" } } });
Employees = emps;
this.DataContext = this;
}
public List<Employee> Employees { get; set; }
}
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public List<Manager> Details { get; set; }
}
public class Manager
{
public int ManagerID { get; set; }
public string ManagerName { get; set; }
}
CustomDataGrid.xaml
<Grid>
<DataGrid ItemsSource="{Binding Employees}" local:DataGridColumnsBehavior.BindableColumns="{Binding Columns, RelativeSource={RelativeSource AncestorType=UserControl}}">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid ItemsSource="{Binding Details}" local:DataGridColumnsBehavior.BindableColumns="{Binding RowDetailColumns, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
CustomDataGrid.xaml.cs
/// <summary>
/// Interaction logic for CustomDataGrid.xaml
/// </summary>
public partial class CustomDataGrid : UserControl
{
public CustomDataGrid()
{
InitializeComponent();
Columns = new ObservableCollection<DataGridColumn>();
RowDetailColumns = new ObservableCollection<DataGridColumn>();
}
public static DependencyProperty ColumnsProperty =
DependencyProperty.Register("Columns"
, typeof(ObservableCollection<DataGridColumn>)
, typeof(CustomDataGrid));
public static DependencyProperty RowDetailColumnsProperty =
DependencyProperty.Register("RowDetailColumns"
, typeof(ObservableCollection<DataGridColumn>)
, typeof(CustomDataGrid));
public ObservableCollection<DataGridColumn> Columns
{
get { return (ObservableCollection<DataGridColumn>)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
public ObservableCollection<DataGridColumn> RowDetailColumns
{
get { return (ObservableCollection<DataGridColumn>)GetValue(RowDetailColumnsProperty); }
set { SetValue(RowDetailColumnsProperty, value); }
}
}
DataGridColumnsBehavior.cs ///列的附加属性
public static 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();
if (ne.NewItems != null)
{
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);
}
}
问题:使用代码,我能够绑定父DataGrid的列并且它按预期工作,但是在childDatagrid中的 (在RowDetail中)我可以看到只有第一行的详细信息和休息时抛出的异常 。
例外详情:
关于如何解决此问题的任何想法?
答案 0 :(得分:2)
尝试使用此代码
替换附加行为的第32行(在BindableColumnsPropertyChanged
中)
foreach (DataGridColumn column in columns)
{
DataGridTextColumn col = new DataGridTextColumn() ;
col.Binding = ((DataGridTextColumn)column).Binding;
col.Header = column.Header;
dataGrid.Columns.Add(col);
}