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)
小智 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用来切换ContentTemplate它ContentPresenter,这样上面两个模板就可以通过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
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,您不会遇到性能成本或复杂性.