我有一个包含三列的 WPF Datagrid。前两列 DataGridComboBox Columns。第三列是 Template 列,里面有 ContentControl。我想将此 Datagrid 用作高级搜索的数据输入表单。第一列将与数据库中有关文档的属性列表(如 DocumentName、OwnerName、DateCreated 等)绑定。第二列将是运算符列表 (<,<=,!=)。这些运算符将根据从单元格 [0] 中的组合框中选择的属性动态更改。这是在第一个组合框的 SelectionChanged 事件中处理的。
在内容控件(在单元格 [2] 中)内,我需要加载一个 DataTempalte(每个都包含不同的 UI 控件,如 autocompleteBox、DatePicker 等),该控件基于在第一列的组合框中选择的属性在窗口的资源中定义。为此,我添加了一个自定义模板选择器。但我无法访问 DataGrid ComboxBox 及其 DataTempalte 选择器代码中第一个单元格的内容。
请注意,我不想将现有数据绑定到数据网格。数据网格将用作数据输入表单。所以我总是希望只在编辑模式下保留前几行中选择的值。
请参考我的 UI 中的示例代码和后面的代码:
public class DocumentSearchProperty
{
public string PropertyName { get; set; }
public string Operator { get; set; }
public string PropertyValue { get; set; }
}
这是我设置为我的数据源的项目源的类。
<DataGrid AutoGenerateColumns="False" Width="Auto" Name="documentPropertyGrid"
ItemsSource="{}"
SelectionMode="Single" CanUserAddRows="True" CanUserDeleteRows="True" CanUserResizeColumns="True" CanUserSortColumns="True"
CanUserResizeRows="False" FrozenColumnCount="0" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" RowHeaderWidth="0"
AlternatingRowBackground="Gainsboro" AlternationCount="2" VerticalContentAlignment="Stretch" VerticalAlignment="Top" VerticalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridComboBoxColumn x:Name="columnProperty" ItemsSource="{}" SelectedItemBinding="{Binding Path=Id}"
Header="Property" Width="170"/>
<DataGridComboBoxColumn x:Name="columnOperator" ItemsSource="{}" SelectedItemBinding="{Binding Path=value}" Header="Operator" Width="170" />
<DataGridTemplateColumn x:Name="PropertyValue" Header="Value" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl x:Name="CntControl">
<ContentControl.Content>1</ContentControl.Content>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
下面的代码用于处理第一个组合框的选择更改事件。在此选择更改事件中,我可以在单元格 [1] 中获取 ComboBox。但我无法在单元格 [2] 中获取 ContentControl。有人可以提出更好的方法来实现这一目标吗?
DataGridRow row = this.documentPropertyGrid.ItemContainerGenerator.ContainerFromIndex(this.documentPropertyGrid.SelectedIndex) as DataGridRow;
ComboBox ele = this.documentPropertyGrid.Columns[0].GetCellContent(row) as ComboBox;
ContentControl contentControl = this.documentPropertyGrid.Columns[2].GetCellContent(row) as ContentControl;
我对网格的第三列作为内容演示者进行了以下更改:
ContentPresenter contentPresenter = this.documentPropertyGrid.Columns[2].GetCellContent(row) as ContentPresenter;
在上述更改之后,我现在可以在comboxBox 列的SelectionChanged 事件中(在第一列中)动态地将数据模板分配给contentPresenter,如下所示。
DataTemplate dt = new DataTemplate();
switch (propertyName)
{
case "DocumentName":
dt = this.FindResource("AutoCompleteBoxTemplate") as DataTemplate;
break;
case "DateCreated":
case "DateModified":
case "DateAccessed":
dt = this.FindResource("DatePickerTemplate") as DataTemplate;
break;
default:
dt = this.FindResource("AutoCompleteBoxTemplate") as DataTemplate;
break;
}
contentPresenter.ContentTemplate = dt;
但是现在在第二列中,我设置的运算符值被所有行中的最新运算符替换。例如,如果在第一个组合框中选择的属性是 TemplateName,则会有一个包含两个运算符(Equal、NotEqual)的列表。但是,当在第一个组合框中选择 DateCreated 时,第二行中的运算符列应显示 (<,<=,>,>=)。但是由于我使用comboxColumn(columnOperator) 的名称来分配这些运算符,因此第一行中的运算符也使用DateCreated 的运算符进行了更新。如何恢复前几行的值?