C# 属性更改时启动长时间运行的任务以填充另一个属性
好的,所以我试图自学MVVM模式和WPF,我遇到了一个障碍 我有一个ViewModel,它有一个“SelectedProduct”字段。设置SelectedProduct字段后,我想通过调用长时间运行的函数来填充另一个属性“BindedLimits”的内容(根据所选的产品,大约需要2-10秒)。理想情况下,我希望在后台启动更新,并在更新过程中显示一个“进度”窗口,但我似乎找不到任何可靠的资源来说明如何完成更新,或者这是否是这样做的“正确”方式 这是迄今为止我的ViewModelC# 属性更改时启动长时间运行的任务以填充另一个属性,c#,wpf,mvvm,C#,Wpf,Mvvm,好的,所以我试图自学MVVM模式和WPF,我遇到了一个障碍 我有一个ViewModel,它有一个“SelectedProduct”字段。设置SelectedProduct字段后,我想通过调用长时间运行的函数来填充另一个属性“BindedLimits”的内容(根据所选的产品,大约需要2-10秒)。理想情况下,我希望在后台启动更新,并在更新过程中显示一个“进度”窗口,但我似乎找不到任何可靠的资源来说明如何完成更新,或者这是否是这样做的“正确”方式 这是迄今为止我的ViewModel public c
public class LimitsViewModel : PropertyChangedBase
{
private ProductFamily selectedProduct;
public ProductFamily SelectedProduct
{
get { return this.selectedProduct; }
set
{
bool runLongOperation = true;
if (value == this.selectedProduct)
{
runLongOperation = false;
}
this.SetPropertyChanged(ref this.selectedProduct, value);
if (runLongOperation)
{
this.Limits = LoadLimits();
}
}
}
private ObservableCollection<BindedLimit> limits;
public ObservableCollection<BindedLimit> Limits
{
get { return this.limits; }
set
{
this.SetPropertyChanged(ref this.limits, value);
}
}
private BindedLimit selectedLimit;
public BindedLimit SelectedLimit
{
get { return this.selectedLimit; }
set
{
this.SetPropertyChanged(ref this.selectedLimit, value);
}
}
private ObservableCollection<BindedLimit> LoadLimits()
{
// Long running stuff here
}
}
public class LimitsViewModel:PropertyChangedBase
{
私人产品系列精选产品;
公共产品系列精选产品
{
获取{返回this.selectedProduct;}
设置
{
bool runlong操作=真;
如果(值==此.selectedProduct)
{
runLongOperation=false;
}
this.SetPropertyChanged(参考this.selectedProduct,value);
if(长时间运行)
{
this.Limits=LoadLimits();
}
}
}
私人可观测收集限额;
公共可观测收集限值
{
获取{返回this.limits;}
设置
{
this.SetPropertyChanged(参考this.limits,value);
}
}
私有绑定限制selectedLimit;
公共绑定限制SelectedLimit
{
获取{返回this.selectedLimit;}
设置
{
this.SetPropertyChanged(参考this.selectedLimit,value);
}
}
私有ObservableCollection负载限制()
{
//这里有长跑的东西
}
}
类似
private ProductFamily _selectedProduct;
public ProductFamily SelectedProduct
{
get { return _selectedProduct; }
set
{
this.SetPropertyChanged(ref _selectedProduct, value)
Limits.Clear(); // or Limits = new ...
Task.Run(() => LongTask());
}
}
private void LongTask()
{
var list = new List<BindedLimit>();
...
App.Current.Dispatcher.Invoke(() => Limits = new ObservableCollection<BindedItems>(list));
}
private ProductFamily\u选择的产品;
公共产品系列精选产品
{
获取{return\u selectedProduct;}
设置
{
此.SetPropertyChanged(参考所选产品,值)
Limits.Clear();//或Limits=new。。。
Task.Run(()=>longstask());
}
}
私人有限公司
{
var list=新列表();
...
App.Current.Dispatcher.Invoke(()=>Limits=newobserveCollection(list));
}
Sinatr的链接帮助我找到了解决方案。这是我设计的。谢谢
public class LimitsViewModel : PropertyChangedBase
{
private CancellationTokenSource tokenSource;
public LimitsViewModel()
{
this.tokenSource = new CancellationTokenSource();
}
public ICommand LoadCommand
{
get { return new RelayCommand(async x => await this.LoadLimits(this.tokenSource.Token)); }
}
private ProductFamily selectedProduct;
public ProductFamily SelectedProduct
{
get { return this.selectedProduct; }
set
{
this.SetPropertyChanged(ref this.selectedProduct, value);
this.LoadCommand.Execute(null);
}
}
private ObservableCollection<BindedLimit> limits;
public ObservableCollection<BindedLimit> Limits
{
get { return this.limits; }
set { this.SetPropertyChanged(ref this.limits, value); }
}
private bool limitsLoading;
public bool LimitsLoading
{
get { return this.limitsLoading; }
set { this.SetPropertyChanged(ref this.limitsLoading, value); }
}
private BindedLimit selectedLimit;
public BindedLimit SelectedLimit
{
get { return this.selectedLimit; }
set { this.SetPropertyChanged(ref this.selectedLimit, value); }
}
private async Task LoadLimits(CancellationToken ct)
{
}
}
public class LimitsViewModel:PropertyChangedBase
{
私有取消令牌源令牌源;
public LimitsViewModel()
{
this.tokenSource=新的CancellationTokenSource();
}
公共ICommand LoadCommand
{
获取{return new RelayCommand(async x=>wait this.LoadLimits(this.tokenSource.Token));}
}
私人产品系列精选产品;
公共产品系列精选产品
{
获取{返回this.selectedProduct;}
设置
{
this.SetPropertyChanged(参考this.selectedProduct,value);
this.LoadCommand.Execute(null);
}
}
私人可观测收集限额;
公共可观测收集限值
{
获取{返回this.limits;}
set{this.SetPropertyChanged(ref this.limits,value);}
}
私人布尔有限公司;
公共图书馆有限公司
{
获取{返回this.limitsLoading;}
set{this.SetPropertyChanged(ref this.limitsLoading,value);}
}
私有绑定限制selectedLimit;
公共绑定限制SelectedLimit
{
获取{返回this.selectedLimit;}
set{this.SetPropertyChanged(ref this.selectedLimit,value);}
}
专用异步任务负载限制(CancellationToken ct)
{
}
}
可观察收集
需要UI线程。您可以在后台准备列表
(使用线程
、任务
等),然后调用可观察集合的更新
。看,好吧,我不知道可观测的收集。因此,如果我在您发送给我的链接中实现该命令,我如何在选择更改时调用它?我是否只调用Command.Execute在setter中执行?