以编程方式更改属性值C#后,WPF XAML数据触发器无法触发

时间:2017-10-31 13:44:41

标签: 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="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>

这一切都很好,但我发现只要我在后面的代码中更改背景颜色,上面的MouseOver和MouseDown触发器就不会再触发了。

RowHeaderButton rhb = RowHeadersColumn.VisibleRowHeaders[cell.CellInfo.RowIndex];
rhb.Background = new SolidColorBrush(Color.FromArgb(100, 83, 195, 213));

我对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。

2 个答案:

答案 0 :(得分:2)

触发器正在触发,但是他们的重置器被覆盖。

这是由于CMake documentation about 'set' command。如果Background属性是以编程方式设置的,或者是XAML中的属性,则该值将覆盖任何样式设置器提供的任何值。通常,这是理想的行为:您希望能够覆盖样式在单个控件上执行的操作。

解决方法是在样式触发器中执行所有背景画笔更改。您的代码背后必须有一些理由设置背景画笔。无论如何,找到一种方法来使用触发器。在viewmodel上设置属性并在该属性上写入触发器。

如果您需要帮助将高级抽象转换为您自己的代码,请分享足够的代码以便我了解代码隐藏设置背景的原因和位置,以及您对视图模型的具体内容(如果有的话)。

答案 1 :(得分:1)

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

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>

在我后面的代码中,我使用:

设置值
RowHeaderButton rhb = RowHeadersColumn.VisibleRowHeaders[cell.CellInfo.RowIndex];
rhb.IsCellSelected = true; //or false

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