简体   繁体   English

如何绑定 ObservableCollection 中所有项目的 Time-Dependent-Property<class-with-a-time-dependent-property> 到一个文本框?</class-with-a-time-dependent-property>

[英]How to binding Time-Dependent-Property of all the items in ObservableCollection<Class-with-a-Time-Dependent-Property> to a TextBox?

I have lots kind of tasks (instances of TaskClass) stored in a ObservableCollection named TaskCollection.我有很多类型的任务(TaskClass 的实例)存储在名为 TaskCollection 的 ObservableCollection 中。 In class TaskClass, there was a TimeLeft property which changed dynamically when the task is running.在 class TaskClass 中,有一个 TimeLeft 属性在任务运行时动态更改。

class TaskClass:INotifyPropertyChanged
{
    TimeSpan TimeLeft{get;set;}
}

When one or more tasks were running, user could add some new tasks to TaskCollection.When a task is running, the task's TimeLeft property changed (increase or decrease).当一个或多个任务正在运行时,用户可以向 TaskCollection 添加一些新任务。当一个任务正在运行时,该任务的 TimeLeft 属性发生了变化(增加或减少)。

A TextBox was used in the UI to display the total time needed for all tasks. UI 中使用了一个 TextBox 来显示所有任务所需的总时间。 I've tried to use a multi-bind to both TaskCollection and TaskCollection.Count.我尝试对 TaskCollection 和 TaskCollection.Count 使用多重绑定。 The total time will display in the TextBox just after user add/remove tasks.用户添加/删除任务后,总时间将显示在文本框中。 But when the existed task running (the TimeLeft property changes), the TextBox cannot notify.但是当现有任务运行时(TimeLeft 属性发生变化),TextBox 无法通知。

How to binding TimeLeft prop of all the tasks stored in ObservableCollection to a TextBox, so that the total time left could display in time?如何将存储在 ObservableCollection 中的所有任务的 TimeLeft 属性绑定到 TextBox 中,以便及时显示剩余的总时间?

But when the existed task running (the TimeLeft property changes), the TextBox cannot notify.但是当现有任务运行时( TimeLeft属性发生变化), TextBox无法通知。

This is because there is no notification for any of the data-bound properties when an individual TimeLeft property is set.这是因为在设置单个TimeLeft属性时,没有任何数据绑定属性的通知。

What you should do is to add a property to the view model that returns the sum of all TimeSpan s.您应该做的是向视图 model 添加一个属性,该属性返回所有TimeSpan的总和。 You would then implement the logic to set this property in the view model where it belongs.然后,您将在其所属的视图 model 中实现设置此属性的逻辑。 Something like this:像这样的东西:

public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        Tasks.CollectionChanged += OnTasksCollectionChanged;
    }

    public ObservableCollection<TaskClass> Tasks { get; } = 
        new ObservableCollection<TaskClass>();

    public TimeSpan TotalTimeLeft => new TimeSpan(Tasks.Sum(x => x.TimeLeft.Ticks));

    private void OnTasksCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
            foreach (object task in e.NewItems)
                (task as INotifyPropertyChanged).PropertyChanged
                    += new PropertyChangedEventHandler(OnTaskPropertyChanged);

        if (e.OldItems != null)
            foreach (object task in e.OldItems)
                (task as INotifyPropertyChanged).PropertyChanged
                    -= new PropertyChangedEventHandler(OnTaskPropertyChanged);

        NotifyPropertyChanged(nameof(TotalTimeLeft));
    }

    private void OnTaskPropertyChanged(object sender, PropertyChangedEventArgs e) =>
        NotifyPropertyChanged(nameof(TotalTimeLeft));

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM