wpf数据触发器值没有更新

本文关键字:更新 数据 触发器 wpf | 更新日期: 2023-09-27 18:09:04

我正在尝试制作一个简单的Unity独立构建启动器(用于街机柜)-设置非常简单-操纵杆上下突出显示游戏(在这种情况下改变矩形的填充颜色和button1启动正确的游戏)。我愚蠢地认为我可以简单地在wpf中做到这一点,但是在第一个障碍上就被绊倒了。

我有键盘输入(街机操纵杆是通过I -pac2设置的)工作(主窗口上的焦点锁定),并且正在从0-6更改整数。这通过主窗口上的代码工作,并传递给一个名为position的静态int。

然后我打算根据这个int值高亮显示一系列矩形。我一直在一个矩形上进行测试——使用datattrigger来执行状态的改变——但它不会在键盘输入时更新。代码片段…

  <Rectangle x:Name="gameRect01" Height="74" Margin="10,93,32.667,0" VerticalAlignment="Top" Grid.ColumnSpan="2" IsEnabled="False">
        <Rectangle.DataContext>
            <local:Launcher/>
        </Rectangle.DataContext>
        <Rectangle.Style>
            <Style TargetType="Rectangle">
                <Setter Property="Fill" Value="Red" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path = cursorPos, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" Value="1">
                        <Setter Property="Fill" Value="Green" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Rectangle.Style>

和Launcher类…

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Diagnostics;
    using System.ComponentModel;
    namespace GameLauncher 
    {
      class Launcher : INotifyPropertyChanged
      {
        public static int position = 0;
    public int cursorPos
    {
        get 
        { return position; 
        }
        set
        {
            cursorPos = position;
            RaisePropertyChanged("cursorPos");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public virtual void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }
}

}

XAML代码似乎与cursorPos绑定-如果我更改绑定中的值,矩形将更改填充。

键盘输入肯定改变了位置的值,但值在cursorPos内没有更新。

我觉得我错过了一些非常简单的东西,但找不到任何有帮助的东西(我在过去的3个晚上一直在搜索和尝试修改,没有运气)。如果能给新手一些指点,我将非常感激。

谢谢,彼得。

我已经根据下面的反馈更新了启动器到…

namespace GameLauncher 
{
class Launcher : INotifyPropertyChanged
{
    private int _position;
    public int cursorPos
    {
        get {
            return _position;
        }
        set {
            _position = value;
            RaisePropertyChanged(nameof(cursorPos));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public virtual void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

和我的键盘输入代码看起来像这样…

namespace GameLauncher
{ 
public partial class MainWindow : Window
{
    Launcher launcher = new Launcher();
    private string gameGet;

    public MainWindow()
    {
        InitializeComponent();
        this.KeyDown += new KeyEventHandler(OnButtonKeyDown);
    }
    public void OnButtonKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Down || e.Key == Key.F) {
            launcher.cursorPos =  Math.Min(6, launcher.cursorPos + 1); Debug.WriteLine(launcher.cursorPos);
        }
        if (e.Key == Key.Up || e.Key == Key.R) {
            launcher.cursorPos = Math.Max(0, launcher.cursorPos - 1); Debug.WriteLine(launcher.cursorPos);
        }
        if (e.Key == Key.LeftCtrl || e.Key == Key.LeftAlt || e.Key == Key.A || e.Key == Key.S || e.Key == Key.D1 || e.Key == Key.D2){
         //   gameGet = "testGame";
        }
    }
    private void PlayButton_Click(object sender, RoutedEventArgs e)
    {
      //  Launcher.PlayGame("test");
    }
}

}

XAML代码是相同的,但它没有更新- gah。我现在唯一能想到的是,通过实例化Launcher类在主窗口中调用是不正确的,我应该做另一种方式?

wpf数据触发器值没有更新

一般来说,让您的字段私有并允许访问属性是一个好主意:

 public static int position = 0;
应该

 private /*static*/ int position = 0;

我把static注释掉了,因为你应该只在真正需要的时候使用它。

将所有position = ...;替换为cursorPos = ...;。如果你比我聪明,你甚至可以为它写一个RegEx,让IDE做你的工作;-)

另一点是,如果你使用c# 6.0 RaisePropertyChanged(nameof(cursorPos));,你可以使用关键字的名称来改变属性事件。如果有一天您重命名您的属性,这将为您节省一些麻烦。

编辑

 public int cursorPos
    {
        get 
        { return position; 
        }
        set
        {
            postion = value;  // if you call for example "cursorPos = 12;" the value is "12". this is how properties work...
            RaisePropertyChanged(nameof(cursorPos));
        }
    }