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