WPF DataGrid - 在行选中/失去焦点时防止颜色变化

5

我希望在数据网格失去焦点并选中其中一行时,防止程序更改该行颜色。目前我的代码如下:

        <DataGrid.Resources>
            <SolidColorBrush 
            x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                     Color="Red"/>
        </DataGrid.Resources>

我正在寻找类似以下内容的东西:

颜色="保持不变"

3个回答

9

您需要为DataGridCell样式自定义IsSelected属性触发器/多触发器,如下所示:

    <Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridCell}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                        <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
            </Trigger>
            <Trigger Property="IsKeyboardFocusWithin" Value="True">
                <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsSelected" Value="true"/>
                    <Condition Property="Selector.IsSelectionActive" Value="false"/>
                </MultiTrigger.Conditions>
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            </MultiTrigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
            </Trigger>
        </Style.Triggers>
    </Style>

然后应用您的自定义样式:

        <DataGrid ItemsSource="{Binding Data}" CellStyle="{DynamicResource DataGridCellStyle1}"/>

在这里输入图片描述


编辑:添加完整的XAML代码:

MainWindow.xaml:

<Window x:Class="WpfApplication333.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication333"
    mc:Ignorable="d"
    Title="MainWindow" 
    Height="300" 
    Width="300">

<Window.Resources>

    <Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridCell}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                        <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
            </Trigger>
            <Trigger Property="IsKeyboardFocusWithin" Value="True">
                <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsSelected" Value="true"/>
                    <Condition Property="Selector.IsSelectionActive" Value="false"/>
                </MultiTrigger.Conditions>
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            </MultiTrigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
            </Trigger>
        </Style.Triggers>
    </Style>

</Window.Resources>

<Window.DataContext>
    <local:MyViewModel/>
</Window.DataContext>

<Grid>

    <DataGrid x:Name="dataGrid" ItemsSource="{Binding Data}" HorizontalAlignment="Left" Margin="8,7,0,0" VerticalAlignment="Top" Height="248" Width="113" CellStyle="{DynamicResource DataGridCellStyle1}"/>
    <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="143,116,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

</Grid>


我在我的帖子中添加了完整的XAML,请查看我的EDIT - jsanalytics
在你的编辑之前,我设法让它工作了,尽管如此,你的答案完全解决了我的问题。谢谢。 - JanRad

1

虽然已经有点晚了,但我想分享一下我的方法。因为在2023年,我在互联网上找不到任何可行的解决方案。

简短回答:

    private void DataGrid_LostFocus(object sender, RoutedEventArgs e)
    {
        (sender as DataGrid)?.SelectedIndex = -1;
    }

但是,如果您关心选择,您需要监听两个事件:

    private void DataGrid_LostFocus(object sender, RoutedEventArgs e)
    {
        DataGrid? dg = sender as DataGrid;
        if (dg == null)
            return;
        
        // Try to store indexes like row indexes, column indexes.
        // And then just remove selections
        // If you want to know what was selected before it lost focus,
        // you could create properties for the indexes you stored.

        dg.SelectedIndex = -1;
    }

    private void dataGrid_GotFocus(object sender, RoutedEventArgs e)
    {
        // Restore selection if needed
    }

因此,关键是根本不要有“非活动选择”。您存储然后删除所有选择,然后当您重新获得焦点时,恢复选择。

当您有一些依赖于选择更改的内容时,请注意,因为此解决方案将引发许多选择更改事件。

希望这能帮助到某些人。


0

以下代码对我有效...

 <UserControl.Resources>
        <Style x:Key="DataGridCellStyle" TargetType="DataGridCell">
            <!--DISPLAY CONTENT IN MIDDLE-->
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridCell}">
                        <Grid Background="{TemplateBinding Background}">
                            <ContentPresenter VerticalAlignment="Center" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <!--style triggers added to keep the selection color active on lost focus in datagrid-->
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="#005691"/>
                    <Setter Property="Foreground" Value="White"/>
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
                </Trigger>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsSelected" Value="true"/>
                        <Condition Property="Selector.IsSelectionActive" Value="false"/>
                    </MultiTrigger.Conditions>
                    <Setter Property="Background" Value="#005691"/>
                    <Setter Property="Foreground" Value="White"/>
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                </MultiTrigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
</UserControl.Resources>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接