关于 mvvm:Windows Phone 7 Application – INPC 问题

Windows Phone 7 Application - INPC problems

我是第一次做 WP7 应用程序,我正在尝试使用 MVVM 模式。
我正在制作闹钟,这就是我所拥有的:

视图 - MainView.xaml

1
2
3
...
 <TextBox Text="{Binding Hour, Mode=TwoWay}"></TextBox>
...

型号 - AlarmClock.cs:

1
2
3
4
5
6
7
8
9
10
11
...

private string _second = 22;
  public string Second {
        get { return _second; }
        set {
            _second = value;
            OnPropertyChanged("Second");
        }
    }
...

ViewModel - MainViewModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
private AlarmClock alarmClock;

public MainViewModel() {
    alarmClock = new AlarmClock();
}

public string Second {
        get { return alarmClock.Second; }
        set {
            alarmClock.Second = value;
            OnPropertyChanged("Second");
        }
    }

在 MainView.xaml.cs 中,我将数据上下文设置为
this.DataContext = new ViewModel();

ViewModel 和 Model 都实现了 INotifyPropertyChanged 接口。

我的问题是:在模型中,我有一个每秒滴答一次的 DispatcherTimer。当我这样做时:

秒 = 23;

我的视图(我的文本框)没有更新,也没有显示 _second 的值。但是如果我在文本框中写一些东西,那么我的模型似乎是用输入的值更新的。

有人能看到我做错了什么吗?

提前谢谢你,
彼得


您的示例中给出的属性名称和类型有点令人困惑,但我认为您的情况的主要问题如下:

您的 MainViewModel 中有一个类型为 AlarmClock 的属性。您有一个 MainViewModel 实例作为 MainView.xamlDataContext。我看到您将 MainViewModelSecond 属性委托给 AlarmClock 实例。当更改来自 UI 时,这很棒,但我认为您的 DispatcherTimer 在 AlarmClock 实例上运行,但该实例没有任何观察者(因为 UI 侦听 MainViewModel 实例)。

您有多个选项可以使其工作,但我对这种情况的建议是扩展 TextBox 绑定路径并将其直接绑定到 AlarmClock 实例。当然你需要在 MainViewModel:

上暴露 AlarmClock

1
2
3
4
5
6
7
8
9
10
private AlarmClock alarmClock;

public MainViewModel() {
    alarmClock = new AlarmClock();
}

public AlarmClock AlarmClock
{
    get { return alarmClock; }
}

然后改变你的xaml:

1
<TextBox Text="{Binding AlarmClock.Hour, Mode=TwoWay}"></TextBox>

另一种选择是订阅 MainViewModel 内的 AlarmClock 实例 PropertyChanged 事件,将其委托给 UI,但这很麻烦。您也可以更改 DispatcherTimer 以在 MainViewModel 上运行,但我认为它不属于那里。