将控件的前景色绑定到鼠标悬停

Binding foreground color of control to mouse hover

我有一个用户控件,我必须根据鼠标悬停、单击或 none 更改颜色。遵循 MVVM。这是我的代码:

XAML

中的用户控件
<userControls:NC DataContext="{Binding NCVM}" >
 
</userControls:NC>

用户控件视图模型

public class NCVM : ObservableObject
{

    public NCVM()
    {

    }

    private NCState _currentState = NCState.InActive;
    public NCState CurrentState
    {
        get => _currentState;
        set
        {
            _currentState = value;

            switch (_currentState)
            {
                case NCState.InActive:
                    ForegroundColor = System.Windows.Media.Brushes.LightGray;
                    IsActive = false;
                    break;
                case NCState.Active:
                    ForegroundColor = System.Windows.Media.Brushes.White;
                    IsActive = true;
                    break;
                case NCState.Hovered:
                    ForegroundColor = System.Windows.Media.Brushes.White;
                    IsActive = false;
                    break;
                default:
                    ForegroundColor = System.Windows.Media.Brushes.LightGray;
                    IsActive = false;
                    break;
            }
        }
    }

    public bool _isActive;
    public bool IsActive
    {
        get => _isActive;
        set => SetProperty(ref _isActive, value);
    }

    private System.Windows.Media.Brush _foregroundColor = System.Windows.Media.Brushes.LightGray;

    public System.Windows.Media.Brush ForegroundColor
    {
        get => _foregroundColor;
        set => SetProperty(ref _foregroundColor, value);
    }


}

主要Window视图模型

public class MWVM : BVM
{
    #region Private Variables
    private NCVM _NCVM = new();
    #endregion

    public MWVM()
    {
        NCVM.CurrentState = NCState.Active;
    }

    #region Public Properties
    public NCVM NCVM
    {
        get => _NCVM;
        set => SetProperty(ref _NCVM, value);
    }
    #endregion
}

现在,它正在预设为活动状态以供检查。现在,我必须将其设置为手动,以便它在悬停时发生变化,但不知道如何进行绑定。

您可以查看 EventTrigger 或一般触发器来设置控件的样式。

*编辑: 举个小例子,不考虑MVVM,仅供大家一窥触发器。

用户控件:

<UserControl x:Class="WpfApp1.UserControl1"
             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:WpfApp1"
             mc:Ignorable="d" 
             d:DataContext="{d:DesignInstance Type={x:Type local:UserControl1}}"
             Height="200" Width="400">
    <UserControl.Style>
        <Style TargetType="UserControl">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMyPropSet}" Value="True">
                    <Setter Property="Background" Value="Turquoise"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </UserControl.Style>
    <GroupBox Header="I am your usercontrol">
        <Button Width="100" Height="35" Content="Toggle Property" Click="Button_Click"/>
    </GroupBox>
</UserControl>

和code-behind:

    public partial class UserControl1 : UserControl, INotifyPropertyChanged
{
    public UserControl1()
    {
        InitializeComponent();
        DataContext = this;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public bool IsMyPropSet { get; set; }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        IsMyPropSet = !IsMyPropSet;
        RaisePropertyChanged(nameof(IsMyPropSet));
    }

    protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

MVVM 模式是关于将用户界面(视图)与数据和应用程序逻辑本身分开。您的示例违反了 MVVM,因为它将画笔和视觉状态存储在视图模型中。视图模型应该只暴露要绑定的数据和命令,而不是用户界面元素,并且它不能包含与用户界面相关的逻辑,就像管理视觉状态或外观一样。它经常被误解为 创建视图模型并将所有内容放在那里

对于你的情况,我认为你可以通过将所有内容都移动到一个样式中来解决你的问题。以下 XAML 应显示您的 userControls:NC。有不同状态的触发器,例如 DisabledHover / Mouse Over。请注意,您需要设置一个Background,否则该控件不参与命中测试,例如IsMouseOver 属性 不会是 True 即使你将鼠标悬停在它上面。无后台使用Transparent(不等于不设置值)

<UserControl ...>
   <UserControl.Style>
      <Style TargetType="{x:Type userControls:NC}">
         <!-- Background must be set at least to "Transparent" -->
         <Setter Property="Background" Value="Black"/>
         <!-- Default -->
         <Setter Property="Foreground" Value="LightGray"/>
         <Style.Triggers>
            <!-- Hovered -->
            <Trigger Property="IsMouseOver" Value="True">
               <Setter Property="Foreground" Value="White"/>
            </Trigger>
            <!-- Disabled -->
            <Trigger Property="IsEnabled" Value="False">
               <Setter Property="Foreground" Value="LightGray"/>
            </Trigger>
         </Style.Triggers>
      </Style>
   </UserControl.Style>

   <!-- Dummy element for demonstration purposes of foreground -->
   <TextBlock Text="This text shows the foreground"/>

</UserControl>