我有一个datagrid,其中列被动态填充。我必须在代码中执行,因为用户可以通过自定义列设置系统添加列/删除列/修改列属性。
我已经创建了一个附加属性作为依赖属性,如下所示:
public class DataGridColumnBehavior
{
public static readonly DependencyProperty ColumnsSourceProperty =
DependencyProperty.RegisterAttached("ColumnsSource",
typeof (ObservableCollection<ColumnDescriptor>),
typeof (DataGridColumnBehavior),
new UIPropertyMetadata(null, ColumnsSourcePropertyChanged));
private static void ColumnsSourcePropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
var dataGrid = source as DataGrid;
var columnDescriptors = e.NewValue as ObservableCollection<ColumnDescriptor>;
if (dataGrid != null && columnDescriptors != null && columnDescriptors.Any())
{
dataGrid.Columns.Clear();
columnDescriptors.ToList().ForEach(col =>
{
var gridColumn = CreateDataGridColumn(col);
if(gridColumn != null)
dataGrid.Columns.Add(gridColumn);
});
}
}
private static DataGridColumn CreateDataGridColumn(ColumnDescriptor columnDescriptor)
{
Type propertyType = null;
if (columnDescriptor.ParentDtoType != null)
propertyType = columnDescriptor.ParentDtoType.GetProperty(columnDescriptor.DataPropertyName).PropertyType;
DataGridBoundColumn returnColumn;
if (propertyType == typeof (bool))
{
returnColumn = new DataGridCheckBoxColumn();
}
else if (propertyType == typeof (string) && columnDescriptor.LookupOn)
{
returnColumn = new DataGridLookupColumn();
}
else if (propertyType == typeof (DateTime?) || propertyType == typeof(DateTime))
{
returnColumn = new DataGridDateColumn();
}
else
{
returnColumn = new DataGridTextColumn();
}
returnColumn.Header = columnDescriptor.HeaderText;
returnColumn.Width = columnDescriptor.Width;
returnColumn.Binding = new Binding(columnDescriptor.DataPropertyName) { UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, Mode = BindingMode.TwoWay };
returnColumn.IsReadOnly = columnDescriptor.TextReadOnly;
returnColumn.Visibility = columnDescriptor.Visible ? Visibility.Visible : Visibility.Collapsed;
return returnColumn;
}
public static void SetColumnsSource(DependencyObject element, ObservableCollection<DataGridColumn> value)
{
element.SetValue(ColumnsSourceProperty, value);
}
public static ObservableCollection<DataGridColumn> GetColumnsSource(DependencyObject element)
{
return (ObservableCollection<DataGridColumn>)element.GetValue(ColumnsSourceProperty);
}
XAML:
<DataGrid Grid.Column="6" Grid.ColumnSpan="5" Grid.RowSpan="5" Grid.Row="8" Name="KorlistaDataGrid" MaxHeight="106" behavior:DataGridColumnBehavior.ColumnsSource="{Binding ColumnsListView}" ItemsSource="{Binding MyObservableCollection}" SelectedItem="{Binding ListViewSelectedItem, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" AutoGenerateColumns="False">
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="XXX" Command="{Binding ContextMenuCommand}" IsEnabled="{Binding CMSIsEnabled, UpdateSourceTrigger=PropertyChanged}"></MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
我的自定义列:
public class DataGridDateColumn : DataGridTextColumn
{
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
var dataGridBoundColumn = cell.Column as DataGridBoundColumn;
var datePicker = new DatePicker { Width = 50, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center };
if (dataGridBoundColumn != null)
{
datePicker.SetBinding(TextBox.TextProperty, dataGridBoundColumn.Binding);
var bindingExpression = datePicker.GetBindingExpression(TextBox.TextProperty);
if (bindingExpression != null)
{
bindingExpression.UpdateSource();
bindingExpression.UpdateTarget();
}
}
return datePicker;
}
}
一切看起来都很棒,我的列就像我想要的那样,我的itemssource中的所有绑定值都被视为预期。
最后我的问题:如何在这里配置绑定,以便:
提前致谢!
答案 0 :(得分:1)
好的,我自己解决了这个问题:)
这有效
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
var dataGridBoundColumn = cell.Column as DataGridBoundColumn;
var datePicker = new DatePicker { Width = 50, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center };
var cellContent = cell.Content as TextBlock;
if (dataGridBoundColumn != null)
{
var bindingExpression = (cell.Content as TextBlock) != null ? BindingOperations.GetBindingExpression(cellContent, TextBlock.TextProperty) : null;
if (bindingExpression != null)
{
var newBindning = new Binding(bindingExpression.ParentBinding.Path.Path)
{
UpdateSourceTrigger = bindingExpression.ParentBinding.UpdateSourceTrigger, Mode = bindingExpression.ParentBinding.Mode
};
datePicker.SetBinding(DatePicker.TextProperty, newBindning);
}
}
return datePicker;
}