我在WPF MVVM中创建了一个动态UI应用程序,它将UI的区域绑定到我自定义的UIField
类的集合。动态设置DataGridColumn的单元格内容
UIField
包含多个BindingProperty
属性,允许我指定Control
将绑定到的属性。
public abstract class UIField : BaseObject
{
BindingProperty property, isReadonly = new BindingProperty(false, false);
object dataContext;
public BindingProperty Property
{
get { return property; }
set { SetProperty(ref property, value,() => Property); }
}
public BindingProperty IsReadonly
{
get { return isReadonly; }
set { SetProperty(ref isReadonly, value,() => IsReadonly); }
}
public object DataContext
{
get { return dataContext; }
set { SetProperty(ref dataContext, value,() => DataContext); }
}
}
在ResourceDictionary
我的模板UIField
<DataTemplate DataType="{x:Type fields:TextBoxField}">
<TextBox metro:TextBoxHelper.Watermark="{e:IndirectBinding Watermark}"
metro:TextBoxHelper.UseFloatingWatermark="{e:IndirectBinding UseFloatingWatermark}"
IsReadOnly="{e:IndirectBinding IsReadonly}"
Text="{e:IndirectBinding Property}"
/>
</DataTemplate>
派生类,然后我在视图中创建模型这些领域,并将它们添加到集合。然后,UI使用ItemsControl
new TextBoxField()
{
DataContext = this,
Property = new BindingProperty(() => ((SalesOrder)Order).SecondSalesReference),
Watermark = new BindingProperty("Customer Ref. Number", false),
UseFloatingWatermark = new BindingProperty(true, false)
}
这是伟大的工作正常的字段,但我遇到一个问题,DataGrid
结合到集合中。
最好,我希望能够绑定的UIField
S作一直延伸到提供一个标题属性设置为DataGrid
的列,然后这些模板来DataGridColumn
个集合,但你不能有一个DataGridColumn
一个DataTemplate
。
目前,我已经创建了一个带给我的头,DataGridColumn
类型,应该是在每个单元的内容的接口:
public interface IDataGridField
{
string Header { get; set; }
Type ColumnType { get; }
UIField CellContents { get; }
}
我然后使用这些绑定到一个DataGrid
小号列:
public class DataGridHelper
{
public static readonly DependencyProperty BindableColumnsProperty = DependencyProperty.RegisterAttached("BindableColumns", typeof(ThreadSafeCollection<IDataGridField>), typeof(DataGridHelper),new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
var dataGrid = source as DataGrid;
var columns = e.NewValue as ThreadSafeCollection<IDataGridField>;
dataGrid.Columns.Clear();
if (columns == null)
return;
foreach (var column in columns)
{
var newColumn = Utility.CreateInstance(column.ColumnType) as DataGridColumn;
newColumn.Header = column.Header;
dataGrid.Columns.Add(newColumn);
}
}
public static void SetBindableColumns(DependencyObject element, ThreadSafeCollection<IDataGridField> value)
{
element.SetValue(BindableColumnsProperty, value);
}
public static ThreadSafeCollection<IDataGridField> GetBindableColumns(DependencyObject element)
{
return (ThreadSafeCollection<IDataGridField>)element.GetValue(BindableColumnsProperty);
}
}
这会给我列标题,但DataGridCell
s没有内容。
如何设置创建的DataGridColumn
中的每个单元格的内容?
EDIT 1(进度):
我意识到,产生的DataGridColumn
必须是一个DataGridTemplateColumn
所以这打开了几个属性。
我修改了IDataGridField
,将UIField
属性更改为Type
。
然后,生成新的DataGridColumn
当我刚刚得到的DataTemplate
分配给所选Type
foreach (var column in columns)
{
var newColumn = new DataGridTemplateColumn();
var key = new DataTemplateKey(column.CellContentType);
var template = Application.Current.FindResource(key) as DataTemplate;
newColumn.CellTemplate = template;
newColumn.Header = column.Header;
dataGrid.Columns.Add(newColumn);
}
我认为唯一的问题正在申请绑定。
这样做的问题是,它会给我相同类型的DataTemplate。我需要能够指定不同的属性(IsReadonly等)。我认为我最好的选择可能是重写DataGridTemplateColumn和GenerateElement() – Blinx