【问题标题】:WPF UserControls; triggers and changing other controlsWPF 用户控件;触发器和更改其他控件
【发布时间】:2011-10-18 03:53:01
【问题描述】:

我创建了一个 WPF 用户控件,其中包含一个按钮和一个组合框。我想根据鼠标的位置更改两者的样式,因此鼠标悬停的 UIElement 为黑色,另一个为红色。如果两者都没有设置样式,则将应用默认样式。

别担心,这个噩梦般的配色方案只是为了说明这个概念!

提前感谢您的帮助。

XAML

<UserControl x:Class="WpfUserControlSample.ToolbarButtonCombo"
             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" 
             xmlns:local="clr-namespace:WpfUserControlSample"
             x:Name="Control"
             mc:Ignorable="d" 
             d:DesignHeight="30">    
    <UserControl.Resources>
        <Style TargetType="{x:Type local:ToolbarButtonCombo}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsButtonMouseOver}" Value="True">
                    <Setter Property="ButtonStyle" Value="Black"/>
                    <Setter Property="ComboStyle" Value="Red"/>                    
                </DataTrigger>
                <!--
                <DataTrigger Binding="{Binding IsComboMouseOver}" Value="True">
                    <Setter Property="ButtonStyle" Value="Red"/>
                    <Setter Property="ComboStyle" Value="Black"/>
                </DataTrigger>
                -->
            </Style.Triggers>
        </Style>
    </UserControl.Resources>
    <StackPanel Orientation="Horizontal" Height="30">
        <Button Name="btn" Background="{Binding ButtonStyle,ElementName=Control,Mode=OneWay}">
            Test
        </Button>
        <ComboBox Name="cmb" Background="{Binding ComboStyle,ElementName=Control,Mode=OneWay}"></ComboBox>
    </StackPanel>
</UserControl>

代码隐藏:

namespace WpfUserControlSample
{
    public partial class ToolbarButtonCombo : UserControl, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }  
        public ToolbarButtonCombo()
        {
            InitializeComponent();
            btn.MouseEnter += new MouseEventHandler(btn_MouseChanged);
            btn.MouseLeave += new MouseEventHandler(btn_MouseChanged);
        }
        void btn_MouseChanged(object sender, MouseEventArgs e)
        {
            OnPropertyChanged("IsButtonMouseOver");
        }


        public bool IsButtonMouseOver
        {
            get { return btn.IsMouseOver; }

        }
        public static readonly DependencyProperty IsButtonMouseOverProperty =
            DependencyProperty.Register("IsButtonMouseOver", typeof(string), typeof(ToolbarButtonCombo), new PropertyMetadata("false"));

        public string ButtonStyle { get; set; }
        public static readonly DependencyProperty ButtonStyleProperty =
            DependencyProperty.Register("ButtonStyle", typeof(string), typeof(ToolbarButtonCombo));

        public string ComboStyle { get; set; }
        public static readonly DependencyProperty ComboStyleProperty =
            DependencyProperty.Register("ComboStyle", typeof(string), typeof(ToolbarButtonCombo));    
    }
}

【问题讨论】:

  • 如果您在 IsButtonMouseOver 中放置断点或在返回之前添加一些 Console.WriteLine,您会看到它永远不会被调用,我不是很有经验,但这部分对我来说似乎很奇怪,我不认为您已正确连接到实际的 IsMouseOver。如果可以的话,我个人会直接使用带有 IsMouseOver 属性的普通触发器,但我是新手,不知道如何更改现有代码。祝你好运。

标签: c# wpf xaml triggers


【解决方案1】:

有两个问题。

首先,您的 DataTrigger 绑定看起来不正确。他们正在寻找 DataContext 上的 IsButtonMouseOver,而不是关联的控件。您需要使用:

<DataTrigger Binding="{Binding IsButtonMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
    <Setter Property="ButtonStyle" Value="Black"/>
    <Setter Property="ComboStyle" Value="Red"/>                    
</DataTrigger>

或者:

<Trigger Property="IsButtonMouseOver" Value="True">
    <Setter Property="ButtonStyle" Value="Black"/>
    <Setter Property="ComboStyle" Value="Red"/>                    
</Trigger>

另一个是你的 IsButtonMouseOver 没有正确实现。你应该这样做:

public static readonly DependencyProperty IsButtonMouseOverProperty = DependencyProperty.Register("IsButtonMouseOver",
    typeof(bool), typeof(ToolbarButtonCombo), new PropertyMetadata(false));

    public bool IsButtonMouseOver
    {
        get { return (bool)this.GetValue(IsButtonMouseOverProperty); }
        set { this.SetValue(IsButtonMouseOverProperty, value); }
    }

    void btn_MouseChanged(object sender, MouseEventArgs e)
    {
        this.IsButtonMouseOver = this.btn.IsMouseOver;
    }

或者更准确地说,将 IsButtonMouseOver 设为只读依赖属性,如下所示:

private static readonly DependencyPropertyKey IsButtonMouseOverPropertyKey = DependencyProperty.RegisterReadOnly("IsButtonMouseOver",
    typeof(bool), typeof(ToolbarButtonCombo), new FrameworkPropertyMetadata(false));

public static readonly DependencyProperty IsButtonMouseOverProperty = ToolbarButtonCombo.IsButtonMouseOverPropertyKey.DependencyProperty;

public bool IsButtonMouseOver {
    get { return (bool)this.GetValue(IsButtonMouseOverProperty); }
    private set { this.SetValue(IsButtonMouseOverPropertyKey, value); }
}

您的其他属性(ButtonStyle 和 ComboStyle)也需要正确实现,并且它们的 get/set 方法不受依赖属性的支持。

【讨论】:

  • 效果很好,我现在可以看到哪里出错了。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 2019-02-27
相关资源
最近更新 更多