2016-09-27 73 views
1

我正在尝试制作一个简单的Unity Standalone构建启动器(用于街机内阁) - 安装程序非常简单 - 操纵杆向上和向下突出显示一个游戏(在这种情况下,更改一个游戏的填充颜色矩形和BUTTON1 lauches正确的游戏。 我傻傻的以为我可以简单地在WPF做到这一点,但在第一道关卡都有所涉猎。wpf DataTrigger值不更新

我有键盘输入(街机摇杆是建立通过I-PAC2)工作(焦点锁定在主窗口上),并且正在改变一个从0到6的整数,这可以通过MainWindow上的代码工作(hurray)并传递到一个叫做的静态int位置

然后,我打算创建一系列基于此int值进行高亮显示的矩形。 我一直在测试一个矩形 - 使用dataTrigger来实现状态的改变 - 但它不会在键盘输入上更新。 代码剪...

<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> 

和启动类...

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。我现在唯一能想到的是通过实例化在MainWindow中调用的Launcher类是不正确的,我应该以另一种方式做它?

+1

如果您分配一个值'cursorPos'属性的PropertyChanged事件仅触发。只需设置“位置”字段将不起作用。 – Clemens

+0

感谢您的快速回复 这是我在看的地方(我曾想过更新集合上的cursorPos会这样做) - 在这种情况下我该怎么做? –

回答

0

总的来说这是一个好主意,使你的领域专用,并给予了性能访问:

public static int position = 0; 

应该

private /*static*/ int position = 0; 

我评论的静态,因为如果这是你应该只使用它真的需要。

全部替换position = ...;cursorPos = ...;。如果你比我聪明,你甚至可以为它编写一个正则表达式,让IDE做你的工作;-)

的另一点是,你可以,如果你使用C#6.0 RaisePropertyChanged(nameof(cursorPos));使用属性更改事件的nameof关键字。如果你有一天重新命名你的房产,这会让你更加头痛。

编辑

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)); 
     } 
    } 
+0

进一步阅读:http://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property-in-c – Mat

+0

谢谢,这真的很有帮助 - 我没有'对这些领域非常了解。 越来越近 - 仍然不是那里:/ 我已经更新到您的建议...并且它看起来很不错,但仍然没有更新 - 在我的MainWindow类中,发出'cursorPos'value Im实例化类到能够调用'cursorPos' ..ie'Launcher launcher = new Launcher();'然后通过'launcher.cursorPos = Math.Min(6,launcher.cursorPos + 1'和'launcher.cursorPos = Math.Min (6,launcher.cursorPos - 1',这是正确的吗? –

+0

我已经更新了问题以包含新代码... –