繁体   English   中英

在 WPF DataGrid 中禁用选择

[英]Disable selecting in WPF DataGrid

如何在 WPFTooklit 的DataGrid禁用选择? 我尝试修改适用于ListView的解决方案(来自WPF ListView 关闭选择),但这不起作用:

<tk:DataGrid>
    <tk:DataGrid.ItemContainerStyle>
        <Style TargetType="{x:Type tk:DataGridRow}">
            <Setter Property="Focusable" Value="false"/>
        </Style>
    </tk:DataGrid.ItemContainerStyle>
    <tk:DataGrid.CellStyle>
        <Style TargetType="{x:Type tk:DataGridCell}">
            <Setter Property="Focusable" Value="false"/>
        </Style>
    </tk:DataGrid.CellStyle>
</tk:DataGrid>

干净的方法是,只覆盖行和单元格的样式

<DataGrid.Resources>
    <ResourceDictionary>
        <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}">
            <Setter Property="Background" Value="{x:Null}" />
            <Setter Property="BorderBrush" Value="{x:Null}" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{x:Null}" />
                    <Setter Property="BorderBrush" Value="{x:Null}" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="Background" Value="{x:Null}" />
            <Setter Property="BorderBrush" Value="{x:Null}" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{x:Null}" />
                    <Setter Property="BorderBrush" Value="{x:Null}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</DataGrid.Resources>

要完全禁用 DataGrid 中的行选择,您可以执行以下操作:

<DataGrid>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="IsHitTestVisible" Value="False"/>
        </Style>
    </DataGrid.RowStyle>
    <!--Other DataGrid items-->
</DataGrid>

这可能被认为比设置<Setter Property="IsEnabled" Value="False"/>更有利,因为执行上述技术会导致行的样式发生变化。 它也不会禁用右键单击时出现的上下文菜单。

最后:请务必注意,将“ IsHitTestVisible ”设置为“ False”会禁用与行的所有交互,包括编辑。

但是,如果您只想更改选中行的样式,请在此处查看答案。

只需将IsHitTestVisible="False"添加到DataGrid定义。

以上所有都是简单黑客的好主意。 然而,他们并没有完全按照要求去做。 其他答案告诉我们如何取消选择用户选择的内容或隐藏用户选择内容的事实。

但是,我理解为什么给出这些答案。 提供真正的解决方案并不容易。

真正的解决方案是首先防止选择,这并不简单,但只需几个简单的步骤就可以做到。

答案 1. 您必须在 Expression Blend 中复制样式(或在某处找到样式的副本)。 2. 更改单个 ItemPresenter 设置。 我在 ItemPresenter 上设置 IsHitTestVisible="False" 就足够了。

如果您需要更多详细信息,或需要对此进行深入了解,请参阅我的博客文章:

如何在 WPF DataGrid 中禁用行选择?

正如 Sonic Soul here所指出的,viky 的解决方案实际上不起作用。

这是在 DataGrid 中禁用选择的实际工作代码:

grid.SelectionChanged += (obj, e) => 
  Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => 
    grid.UnselectAll())); 

我发现这样做的唯一正确方法是禁用 DataGrid Row Style 上的IsHitTestVisible属性。

尽管命名,单击事件仍将注册。 除非您还想禁用滚动,否则请确保不要在整个 DataGrid 上更改此属性。

一种干净的方法是通过静态资源中的新样式(根据需要复制其他设置器)

        <Style x:Key="DataGridUnselectableRowStyle" TargetType="{x:Type DataGridRow}">
            <Setter Property="IsHitTestVisible" Value="False"/>
        </Style>

然后将其绑定到您的 DataGrid 上

        <DataGrid
            RowStyle="{StaticResource DataGridUnselectableRowStyle}" >
            <!-- Contents -->
        </DataGrid>

如果您使用替代颜色:

<Style TargetType="{x:Type DataGrid}">
    <Setter Property="RowBackground" Value="#badeee"/>
    <Setter Property="AlternationCount" Value="2" />
    <Setter Property="AlternatingRowBackground" Value="#92cce5"/>
</Style>

<Style TargetType="{x:Type DataGridCell}">
    <Style.Triggers>           
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="Foreground" Value="Black"/>
        </Trigger>
    </Style.Triggers>
</Style>

<Style TargetType="{x:Type DataGridRow}">
    <Style.Triggers>
        <Trigger Property="ItemsControl.AlternationIndex" Value="0">
            <Setter Property="Background" Value="#badeee"></Setter>
            <Setter Property="BorderBrush" Value="#badeee"></Setter>
        </Trigger>
        <Trigger Property="ItemsControl.AlternationIndex" Value="1">
            <Setter Property="Background" Value="#92cce5"></Setter>
            <Setter Property="BorderBrush" Value="#92cce5"></Setter>
        </Trigger>
    </Style.Triggers>
</Style>

另一种简单的方法是使用 IsSelected 触发器将选择样式更改为透明。

如果其他人面临同样的问题,他们可能会发现它很有帮助。

我们要求在数据网格上禁用几行,但同时允许在它们上使用箭头键导航。 这就是我们必须切换到“IsHitTestVisible”而不是控制“IsEnabled”属性的原因。 所以我们不能采用上述切换到“IsEnable”属性的解决方案。

这是我最终解决这个问题的方法。 我为 DataGridRow 创建了一个新的附加属性 (RowEnable)。 此附加属性可以绑定到视图模型属性以控制“虚拟”启用和禁用。 我还为 DataGridCell 创建了一个新样式,我根据相同的 viewmodel 属性将“IsHitTestVisible”设置为 false。 因此,将其视为鼠标/键盘可以看到但无法看到其单元格/列的行。 这意味着现在我可以根据新的附加属性 (RowEnabled) 设置行的样式以使其看起来禁用/启用。 同时,我可以查看这些实际上已禁用的行的工具提示。

<DataGrid isEnabled="False">
</DataGrid>

这是直接回答您的问题的最简单方法:在 WPF Datagrid 中禁用选择。

我需要一个解决方案背后的代码。 这对我有用:

controlGrid.SelectedCellsChanged += (sender, e) =>
    Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render, new Action(() =>
        controlGrid.UnselectAll()));
controlGrid.Columns.Clear();

因为它有时会闪烁,所以也将 BackgroundProperty 设置为透明。

Style dataGridCellStyle = new Style(typeof(DataGridCell));
Setter newSetterCell = new Setter(DataGridCell.BackgroundProperty, Brushes.Transparent);
dataGridCellStyle.Setters.Add(newSetterCell);
controlGrid.CellStyle = dataGridCellStyle;

这有一个技巧。 您可以处理 DataGrid(例如 dgGrid)的 SelectionChanged 事件并在处理程序中写入:

dgGrid.UnselectAll();

它将取消选择所有选定的行,结果将是“未选择行”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM