C# 以编程方式更改属性值C后,WPF XAML datatrigger无法激发#

C# 以编程方式更改属性值C后,WPF XAML datatrigger无法激发#,c#,wpf,xaml,C#,Wpf,Xaml,我的xaml中有这样一段代码,当我将鼠标悬停并在按钮上单击鼠标时,它会给我的按钮上色 <Border x:Class="DatasetGrid.RowHeaderButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="

我的xaml中有这样一段代码,当我将鼠标悬停并在按钮上单击鼠标时,它会给我的按钮上色

<Border x:Class="DatasetGrid.RowHeaderButton"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" MinWidth="30" Width="Auto">
<Border.Resources>
        <SolidColorBrush x:Key="ButtOverBrush" Color="#53C3D5" Opacity="0.2"></SolidColorBrush>
        <SolidColorBrush x:Key="ButtPressedBrush" Color="#53C3D5" Opacity="0.5"></SolidColorBrush>
</Border.Resources>
    <Border.Style>
        <Style TargetType="Border">
            <Setter Property="Background" Value="Transparent"></Setter>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="{StaticResource ButtOverBrush}"></Setter>
                </Trigger>
                <DataTrigger Binding="{Binding IsMouseDown, RelativeSource={RelativeSource Self}}" Value="True">
                    <Setter Property="Background" Value="{StaticResource ButtPressedBrush}"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>
我是WPF的新手,所以我不确定出了什么问题

编辑:

为了提供更多信息,我上面的控件是RowHeaderButton,即网格的行标题。网格中的每一行都有自己的行标题按钮。因此,当用户悬停或单击它时,它应该从白色变为上面指定的SolidColorBrush

在另一个控件DataGrid.xaml.cs的代码中,我有下面的代码(简化),当选择或不选择网格同一行中的单元格时,该代码将更改行标题的颜色

void UpdateSelectedCells() {            

    foreach (Cell cell in VisibleColumns.SelectMany(c => c.VisibleCells))
        {
            int cellRowIndex = cell.CellInfo.RowIndex;
            cell.IsSelected = SelectedCells.Contains(cell.CellInfo);

            foreach (RowHeaderButton rhb in RowHeadersColumn.VisibleRowHeaders)
            {
                int rowHeaderIndex = Convert.ToInt16(rhb._default.Text) - 1;

                if (cellRowIndex == rowHeaderIndex)
                {
                    if (cell.IsSelected)
                    {
                        rhb.Background = new SolidColorBrush(Color.FromArgb(100, 83, 195, 213));
                    }
                    else
                    {
                        bool rowselected = false;

                        //need to check if any other cell in the row is selected, if not then color row header white
                        foreach (CellInfo celll in SelectedCells)
                        {

                            if (celll.RowIndex == cellRowIndex)
                            {
                                rowselected = true;
                                break;
                            }
                        }

                        if (rowselected == false)
                            rhb.Background = Brushes.White;
                    }
                }
            }
    }
}

我没有用于此的ViewModel。

触发器正在触发,但它们的设置器正在被覆盖

这是由于。如果
Background
属性是以编程方式设置的,或者是作为XAML中的属性设置的,那么该值将覆盖任何样式设置器给它的任何值。通常,这是理想的行为:您希望能够覆盖样式在单个控件上的作用

解决方法是在样式触发器中更改所有背景笔刷。您的代码隐藏必须有一些理由设置背景笔刷。不管那是什么,找到一种用扳机的方法。在viewmodel上设置属性并在该属性上写入触发器


如果您需要帮助将高级抽象转换为您自己的代码,请与我分享足够的代码,让我了解codebehind设置背景的原因和位置,以及您对viewmodel有什么(如果有的话)

我通过创建一个新的dependency属性并将其绑定到数据触发器,解决了这个问题

public bool IsCellSelected
    {
        get { return (bool)GetValue(IsCellSelectedProperty); }
        set { SetValue(IsCellSelectedProperty, value); }
    }
    public static readonly DependencyProperty IsCellSelectedProperty =
        DependencyProperty.Register("IsCellSelected", typeof(bool), typeof(RowHeaderButton), new PropertyMetadata(null));
在我的xaml中,我有:

<DataTrigger Binding="{Binding IsCellSelected, RelativeSource={RelativeSource Self}}" Value="True">
     <Setter Property="Background" Value="{StaticResource ButtPressedBrush}"></Setter>
</DataTrigger>

现在,我的按钮悬停和按钮单击事件不会被覆盖。

谢谢您的回答,现在就有意义了。我会对上面的代码进行编辑,这样你可能更容易理解我在做什么/试图实现什么。我在主要帖子中添加了更多的信息。我不使用视图模型,后面的代码用于DataGrid.xaml.cs,而上面的xaml位于RowHeaderButton中。xaml@nerdalert如果行中有任何选定的单元格,您是否只是给行标题单元格上色?是的,如果行中有任何单元格被选中,我会给行标题上色。它表示该行处于焦点位置。我可能应该进一步简化代码,我还有一些代码可以给列标题上色,这样可能会让人困惑。这种情况下不需要这些代码。是的,RowHeaderButton是我自己的类。此外,DataGrid是一个自定义编写的。在任何情况下,我相信我解决了这个问题,因为我考虑了您最初的建议,即创建一个新的属性来确定是否选择了单元格,并根据ITI对行进行着色。如果您创建一个简单的ViewModel,代码将变得更好,更容易更改GUI,而无需直接更改GUI元素,而是更改与它们绑定的属性。
<DataTrigger Binding="{Binding IsCellSelected, RelativeSource={RelativeSource Self}}" Value="True">
     <Setter Property="Background" Value="{StaticResource ButtPressedBrush}"></Setter>
</DataTrigger>
RowHeaderButton rhb = RowHeadersColumn.VisibleRowHeaders[cell.CellInfo.RowIndex];
rhb.IsCellSelected = true; //or false