禁用在WPF DataGrid中的选择

时间:2010-03-23 00:49:19

标签: c# wpf datagrid focus selection

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

<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>

12 个答案:

答案 0 :(得分:31)

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

<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>

答案 1 :(得分:18)

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

答案 2 :(得分:13)

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

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

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

最后:请注意设置&#34; IsHitTestVisible&#34;到&#34;错误&#34;禁用与行的所有交互,包括编辑。

但是,如果你想要做的只是在选择时更改行的样式,请查看答案here

答案 3 :(得分:10)

以上所有内容都是轻松破解的好主意。但是,他们并没有完全按照要求做。其他答案告诉我们如何取消选择用户选择的内容或隐藏用户选择某些内容的事实。

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

真正的解决方案是首先防止选择,这不是直截了当的,但只需几个简单的步骤即可。

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

如果您需要更多详细信息或深入了解此操作,请参阅我的博文:

How to disable row selection in a WPF DataGrid?

答案 4 :(得分:8)

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

以下是禁用DataGrid中的选择的实际工作代码:

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

答案 5 :(得分:4)

答案 6 :(得分:4)

如果您使用的是替代颜色:

<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>

答案 7 :(得分:3)

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

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

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

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

然后将其绑定在DataGrid上

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

答案 8 :(得分:0)

如果其他人遇到同样的问题,他们可能会觉得有帮助。

我们要求在datagrid上禁用几行,但同时允许对它们进行ARROW键导航。这就是为什么我们不得不切换到'IsHitTestVisible&#39;而不是控制'IsEnabled&#39;属性。所以我们不能采用以上解决方案来切换到'IsEnable&#39;属性。

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

答案 9 :(得分:0)

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

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;

答案 10 :(得分:0)

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

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

答案 11 :(得分:-6)

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

dgGrid.UnselectAll();

它将取消选择所有选定的行,结果将为“No row selected”。