【问题标题】:How can I databind to a constantly-changing property如何将数据绑定到不断变化的属性
【发布时间】:2012-11-12 19:43:26
【问题描述】:

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

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

还有一个包含TextBlockTimer 实例的页面。

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

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

【问题讨论】:

标签: silverlight windows-phone-7 data-binding


【解决方案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
}

【讨论】:

  • 所以本质上,我需要自己定期触发属性更改事件,使用System.Threading.TimerDispatcherTimer - 无法将属性标记为“不稳定”并自动处理?
【解决方案2】:

这是我想出的:

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 事件。

【讨论】:

    【解决方案3】:

    这是你可以做的,你有这个类,

    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 类的当前实例。 为此有很多方法,其中最简单的方法是将网格命名为say(as RootGrid)。 现在在用户控件的加载事件中:

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

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

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

    XAML 中的以上代码,将为您完成。

    【讨论】:

    • 这无济于事 - 我的问题真的是 “如何将 INotifyPropertyChanged 应用于 Value 属性”
    猜你喜欢
    • 1970-01-01
    • 2018-09-10
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2013-10-04
    • 1970-01-01
    • 2021-10-02
    相关资源
    最近更新 更多