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

Posted

技术标签:

【中文标题】在某些条件下使用 ComboBox 只读创建一个单元格 WPF DataGrid【英文标题】:Make a cell with ComboBox readonly on certain conditions WPF DataGrid 【发布时间】:2021-12-16 21:00:16 【问题描述】:

我有什么:

我有一个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个选项:

一个简单的整数 - SelectedValue ObservableCollection&lt;int&gt; - Values

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 模式。

【问题讨论】:

MCR 会有所帮助。话虽如此,您是否尝试过使用转换器?像this 这样的东西也许...... 基本上,单元格可以是值的组合框,也可以只是一个简单的文本块。当Values 内部有值(例如1、2、3)时,1 被预先选择,当您双击单元格时,会出现一个带有其他值的组合框,您可以选择。另一方面,Values 可能为空,我只设置SelectedValue。我希望当Values 为空时,双击单元格时,组合框不会出现。基本上单元格是只读的。不,我没有尝试使用转换器,因为我不知道如何在我的情况下应用它。我希望我解释清楚了。 这是一个需求列表,这不是提问的正确方式。请阅读“How do I ask a good question?”,如果你尽力听从那里的建议,你会得到很好的答案。 【参考方案1】:

当您双击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>

【讨论】:

谢谢你!由于DataGridItemsSourceDataTable,单元格的DataContext 始终为DataRowView,因此dataObject 为空,您对如何进行有什么建议吗? 将其转换为 DataRowView 而不是 YourClass? e.Handled = cell.DataContext is DataRowView dataObject &amp;&amp; ...; 试过这个,但我怎么能访问Values(检查它是否是null)? 试试dataObject["Values"]。或者请询问有关如何从 DataRowView 检索值的新问题。

以上是关于在某些条件下使用 ComboBox 只读创建一个单元格 WPF DataGrid的主要内容,如果未能解决你的问题,请参考以下文章

如何在reactJs中的数组内部条件下禁用某些单选按钮

c# combobox 判断选中

python中如何调整ComboBox宽度

easyui 所有控件只读属性使用教程

easyui 所有控件只读属性使用教程

为什么不能单选按钮是“只读”?