如何制作WPF DataGridCell ReadOnly?

new*_*man 12 wpf readonly datagridcell

我知道你可以准备好整个DataGrid或整个列(IsReadOnly = true).但是,在单元级别,此属性仅准备就绪.但我确实需要这种级别的粒度.有一篇关于在DataGrid是公共领域时通过更改源代码来添加IsReadOnly的博客,但现在我没有DataGrid的源代码.什么是解决方法?

禁用单元格(IsEnabled = false)几乎满足了我的需要.但问题是你甚至无法点击禁用的单元格来选择行(我有完整的行选择模式).

编辑:由于没有人回答这个问题,所以我想这不是一个简单的解决方案.这是一个可能的解决方法:使单元格不可编辑.唯一的问题是单击单元格不会选择行.我刚刚注意到,当单击禁用的单元格时,仍会触发DataGrid的MouseDown或MouseUp事件.在这个事件处理程序中,如果我能找出它单击的行,我可以以编程方式选择行.但是,我无法弄清楚如何从中找到基础行DataGrid.InputHitTest.有人可以给我一些小费吗?

apc*_*apc 13

经过大量的搜索和实验,使用IsTabStop = False和Focusable = False最适合我.

<DataGridTextColumn Header="My Column" Binding="{Binding Path=MyColumnValue}">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell">                                    
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=ReadOnly}" Value="True">                                                    
                    <Setter Property="IsTabStop" Value="False"></Setter>
                    <Setter Property="Focusable" Value="False"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>
Run Code Online (Sandbox Code Playgroud)

  • 这会产生问题的情况是:有一个包含两列的表,第一列是可编辑的,第二列则不可编辑。当焦点位于第一列的一行上时,单击第二列的另一行,您将看到焦点没有改变。新选定的行是蓝色的,但如果用户按键,先前选定的单元格将被编辑。 (2认同)

小智 10

我遇到了同样的问题,单元格应该在某些行中是只读的,而在其他行中则不是.这是一个解决方案:

我们的想法是CellEditingTemplate在两个模板之间动态切换,一个与之相同CellTemplate,另一个用于编辑.这使得编辑模式与非编辑单元格完全相同,尽管它处于编辑模式.

以下是执行此操作的示例代码,请注意此方法需要DataGridTemplateColumn:

首先,为只读和编辑单元格定义两个模板:

<DataGrid>
  <DataGrid.Resources>
    <!-- the non-editing cell -->
    <DataTemplate x:Key="ReadonlyCellTemplate">
      <TextBlock Text="{Binding MyCellValue}" />
    </DataTemplate>

    <!-- the editing cell -->
    <DataTemplate x:Key="EditableCellTemplate">
      <TextBox Text="{Binding MyCellValue}" />
    </DataTemplate>
  </DataGrid.Resources>
</DataGrid>
Run Code Online (Sandbox Code Playgroud)

然后用附加ContentPresenter层定义一个数据模板并Trigger用来切换ContentTemplateContentPresenter,这样上面两个模板就可以通过IsEditable绑定动态切换:

<DataGridTemplateColumn CellTemplate="{StaticResource ReadonlyCellTemplate}">
  <DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
      <!-- the additional layer of content presenter -->
      <ContentPresenter x:Name="Presenter" Content="{Binding}" ContentTemplate="{StaticResource ReadonlyCellTemplate}" />
      <DataTemplate.Triggers>
        <!-- dynamically switch the content template by IsEditable binding -->
        <DataTrigger Binding="{Binding IsEditable}" Value="True">
          <Setter TargetName="Presenter" Property="ContentTemplate" Value="{StaticResource EditableCellTemplate}" />
        </DataTrigger>
      </DataTemplate.Triggers>
    </DataTemplate>
  </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
Run Code Online (Sandbox Code Playgroud)

HTH


Ste*_*nSH 8

DataGridCell.IsReadOnly您可能认为可以绑定的属性,
例如使用XAML,如下所示:

<!-- Won't work -->
<DataGrid Name="myDataGrid" ItemsSource="{Binding MyItems}">
    <DataGrid.Resources>
        <Style TargetType="DataGridCell">
            <Setter Property="IsReadOnly" Value="{Binding MyIsReadOnly}" />
        </Style>
    </DataGrid.Resources>
    <!-- Column definitions... -->
</DataGrid>
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用,因为这个属性是不可写的.
接下来,您可能会尝试拦截并停止鼠标事件,但这不会阻止用户使用F2键进入编辑模式.

我解决这个问题的方法是通过监听PreviewExecutedEventDataGrid,然后有条件地将其标记为已处理.
例如,通过向我的Window或UserControl(或其他更合适的地方)的构造函数添加与此类似的代码:

myDataGrid.AddHandler(CommandManager.PreviewExecutedEvent,
    (ExecutedRoutedEventHandler)((sender, args) =>
{
    if (args.Command == DataGrid.BeginEditCommand)
    {
        DataGrid dataGrid = (DataGrid) sender;
        DependencyObject focusScope = FocusManager.GetFocusScope(dataGrid);
        FrameworkElement focusedElement = (FrameworkElement) FocusManager.GetFocusedElement(focusScope);
        MyRowItemModel model = (MyRowItemModel) focusedElement.DataContext;
        if (model.MyIsReadOnly)
        {
            args.Handled = true;
        }
    }
}));
Run Code Online (Sandbox Code Playgroud)

通过这样做,细胞仍然是可聚焦的和可选择的.
但是除非您的模型项允许用户输入给定行,否则用户将无法进入编辑模式.
通过使用DataGridTemplateColumn,您不会遇到性能成本或复杂性.

  • 好的解决方案 您还可以通过查看*dataGrid.CurrentCell.Column*,使用此代码只读列特定的列行组合. (2认同)
  • 我最后跟着这个,除了我在`DataGrid`上使用`BeginningEdit`事件事件,它给了我args中的`Row`和`Column`,所以我没有弄明白. (2认同)
  • 我真的希望能给你+100。我已经研究了我发现的所有其他建议,但它们都有副作用。这正是我所需要的!!!!荣誉!!!! (2认同)