在某些条件下使用 ComboBox 只读创建一个单元格 WPF DataGrid

Make a cell with ComboBox readonly on certain conditions WPF DataGrid

我有:

我有一个 DataGridTemplateColumn 和一个 ComboBox:

<DataTemplate x:Key="ValuesCellTemplate">
      <TextBlock Text="{Binding Path=SelectedValue, Mode=OneWay}" />
</DataTemplate>
<DataTemplate x:Key="ValuesCellEditingTemplate">
      <ComboBox
            Name="ValuesComboBox"
            DisplayMemberPath="DisplayText"
            ItemsSource="{Binding Path=Value, Mode=OneWay}"
            SelectedValue="{Binding Path=SelectedValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
            SelectedValuePath="DisplayText" />
</DataTemplate>

我正在自动生成列,因此 AutoGeneratingColumn 事件如下所示:

if (e.PropertyName == "First")
{
    var templateColumn = new DataGridTemplateColumn
    {
        Header = e.PropertyName,
        CellTemplate = (sender as FrameworkElement).FindResource("ValuesCellTemplate") as DataTemplate,
        CellEditingTemplate = (sender as FrameworkElement).FindResource("ValuesCellEditingTemplate") as DataTemplate
    };

    e.Column = templateColumn;
}

Values(这是一个 ObservableCollection)是 null 我希望单元格是只读的,这样它就不能进入单元格编辑模式。

本栏目内容有2个选项:

Values里面有值时,当双击单元格(或TextBlock)(也就是说 - 进入CellEditing模式)时,应该出现ComboBox,否则不是。基本上就是这样。

我试过的:

我试过这样做:

<DataTemplate x:Key="ValuesCellTemplate">
      <TextBlock Text="{Binding Path=SelectedValue, Mode=OneWay}" />
</DataTemplate>
<DataTemplate x:Key="ValuesCellEditingTemplate">
      <ComboBox
            Name="ValuesComboBox"
            DisplayMemberPath="DisplayText"
            IsEnabled="{Binding HasItems, RelativeSource={RelativeSource Self}}"
            ItemsSource="{Binding Path=Value, Mode=OneWay}"
            SelectedValue="{Binding Path=SelectedValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
            SelectedValuePath="DisplayText" />
</DataTemplate>

但是当我双击它时,TextBox 变成一个空的只读 ComboBox(进入 CellEditing 模式)。我只是想让它不采取任何行动(只读)(仅当 Valuesnull 时)。

正确的做法是什么?

郑重声明,我使用的是 MVVM 模式。

当您双击 TextBox 时防止 DataGrid 进入编辑模式的一种简单方法是处理单元格的 PreviewMouseDown 事件:

private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    DataGridCell cell = (DataGridCell)sender;
    e.Handled = cell.DataContext is YourClass dataObject && !dataObject.Value.Any();
}
...
var templateColumn = new DataGridTemplateColumn
{
    Header = e.PropertyName,
    CellTemplate = (sender as FrameworkElement).FindResource("ValuesCellTemplate") as DataTemplate,
    CellEditingTemplate = (sender as FrameworkElement).FindResource("ValuesCellEditingTemplate") as DataTemplate,
    CellStyle = (sender as FrameworkElement).FindResource("ReadOnlyCellStyle") as Style,
};

XAML:

<Style x:Key="ReadOnlyCellStyle" TargetType="DataGridCell">
    <EventSetter Event="PreviewMouseDown" Handler="OnPreviewMouseDown" />
</Style>