0

我有一个表示计时器的简单类(为清楚起见进行了简化):

public class Timer {
    DateTime startTime;

    // How do I notify the UI that this property is changing?
    public TimeSpan Value {
        get {
            return DateTime.Now - startTime;
        }
    }
    public void Start() {
        startTime = DateTime.Now;
    }
}

以及一个包含 aTextBlock和 a 的实例的页面Timer

我想对TextBlock'Text属性进行数据绑定以显示Timer.Value. 但是,这个字段显然在不断变化,所以触发PropertyChanged事件似乎没有任何意义。

是否有某种方法可以指示属性始终在变化,以便 UI 尽可能快地更新?

4

3 回答 3

1

PropertyChanged就是设计要做的。UI 应该能够应对不断变化的值。

但是,为了确保您不会淹没 UI,您应该使用一个计时器来控制每个刻度的间隔:

System.Threading.Timer myTimer;

TimerCallback callback = TimerTick;
myTimer = new System.Threading.Timer(callback, null, 0, 1000);

这会立即启动一个计时器 (the 0),它每秒触发一次 (the 1000)。你的TimerCallback会看起来像这样:

void TimerTick(object stateInfo)
{
    // Raise property changed event with DateTime.Now
}
于 2012-11-24T22:26:01.583 回答
1

这就是我想出的:

public class ObservableTimer : Timer, INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    // some extension methods are being used here
    public PropertyChangedEventArgs pcValue = Property.Changed<ObservableTimer>(t => t.Value);

    DispatcherTimer dTimer;

    public ObservableTimer() {
        dTimer = new DispatcherTimer();
        dTimer.Interval = TimeSpan.FromMilliseconds(50);
        dTimer.Tick += onTimerTick;
        dTimer.Start();
    }

    private void onTimerTick(object sender, EventArgs e) {
        // some extension methods are being used here
        PropertyChanged.Raise(this, pcValue);
    }
}

ChrisF 的回答中所述,这使用计时器来定期触发PropertyChanged事件。

于 2012-11-25T13:25:34.570 回答
0

这是你可以做的,你有这门课,

public class Timer {
DateTime startTime;

// How do I notify the UI that this property is changing?
public TimeSpan Value {
    get {
        return DateTime.Now - startTime;
    }
}
public void Start() {
    startTime = DateTime.Now;
}

}

首先将 INotifyPropertyChanged 应用于属性值。

现在在 XAML 中,您可能有一个网格。您需要将网格的“Datacontext”绑定到 Timer 类的当前实例。为此有很多方法,其中最简单的就是将网格命名为say(as RootGrid)。现在在用户控件的加载事件中:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
       RootGrid.DataContext = this;
    }

Ok 游戏结束,最后一步是将 TextBlock 的 Text 属性绑定到您的“Value”。

<TextBlock Text="{Binding Value}"/>

和上面的 XAML 代码,将为您完成。

于 2012-11-25T12:58:55.840 回答