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

TextBlockおよびと のインスタンスを含むページTimer

TextBlockTextプロパティをデータバインドして、 を表示したいと思い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);

これにより、すぐにタイマーが開始され ( 0)、毎秒起動します ( 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's answerで説明されているように、これはタイマーを使用して定期的に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をプロパティValueに適用します。

XAMLでは、グリッドを使用している可能性があります。グリッドの「Datacontext」をTimerクラスの現在のインスタンスにバインドする必要があります。そのためには多くの方法がありますが、その中で最も簡単なのは、グリッドに(RootGridとして)名前を付けることです。ここで、ユーザーコントロールのloadedイベントで:

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

ゲームオーバーです。最後のステップは、TextBlockのTextプロパティを「Value」にバインドすることです。

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

XAMLの上記のコードは、あなたに代わってそれを行います。

于 2012-11-25T12:58:55.840 に答える