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类在主窗口中调用是不正确的,我应该做另一种方式?
一般来说,让您的字段私有并允许访问属性是一个好主意:
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));
}
}