【发布时间】:2014-04-15 17:18:46
【问题描述】:
我尝试实现类似于本文中介绍的模式: http://msdn.microsoft.com/en-us/magazine/dn605875.aspx
以下是我的问题描述:
在我看来,我已经设置:
<Button Content="LoadData" Command="{Binding LoadDataCommand}" />
<ListBox Grid.Row="1" x:Name="listBox" ItemsSource="{Binding DataSource.Result}"
然后在codeBehind中:
this.DataContext = new ProductViewModel();
然后在 ProductViewModel 中:
public AsyncTaskManager<ObservableCollection<Product>> DataSource { get; private set; }
与:
public ProductViewModel()
{
_loadDataCommand = new DelegateCommand(LoadDataAction);
}
private void LoadDataAction(object p)
{
ProductRepository pRepository = new ProductRepository();
DataSource = new AsyncTaskManager<ObservableCollection<Product>>(pRepository.LoadProducts());
}
并且在 AsyncTaskManager PropertyChanged 中始终为 null :( 为什么会这样?绑定有什么问题?
但是当我删除“加载数据”按钮和 _loadDataCommand 并简单地设置时
ProductRepository pRepository = new ProductRepository();
DataSource = new AsyncTaskManager<ObservableCollection<Product>>(pRepository.LoadProducts());
在ProductViewModel 构造函数中,它的工作方式与示例中一样,但我希望用户能够使用构造函数中未启动的按钮调用加载数据:/
下面是 AsyncTaskManager 代码:
using System;
using System.ComponentModel;
using System.Threading.Tasks;
namespace PhoneClientApp.Models
{
public sealed class AsyncTaskManager<TResult> : INotifyPropertyChanged
{
public AsyncTaskManager(Task<TResult> task)
{
Task = task;
if (!task.IsCompleted)
{
var _ = WatchTaskAsync(task);
}
}
private async Task WatchTaskAsync(Task task)
{
try
{
await task;
}
catch
{
}
var propertyChanged = PropertyChanged;
if (propertyChanged == null)
return;
propertyChanged(this, new PropertyChangedEventArgs("Status"));
propertyChanged(this, new PropertyChangedEventArgs("IsCompleted"));
propertyChanged(this, new PropertyChangedEventArgs("IsNotCompleted"));
if (task.IsCanceled)
{
propertyChanged(this, new PropertyChangedEventArgs("IsCanceled"));
}
else if (task.IsFaulted)
{
propertyChanged(this, new PropertyChangedEventArgs("IsFaulted"));
propertyChanged(this, new PropertyChangedEventArgs("Exception"));
propertyChanged(this,
new PropertyChangedEventArgs("InnerException"));
propertyChanged(this, new PropertyChangedEventArgs("ErrorMessage"));
}
else
{
propertyChanged(this,
new PropertyChangedEventArgs("IsSuccessfullyCompleted"));
propertyChanged(this, new PropertyChangedEventArgs("Result"));
}
}
public Task<TResult> Task { get; private set; }
public TResult Result
{
get
{
return (Task.Status == TaskStatus.RanToCompletion)
? Task.Result
: default(TResult);
}
}
public TaskStatus Status
{
get { return Task.Status; }
}
public bool IsCompleted
{
get { return Task.IsCompleted; }
}
public bool IsNotCompleted
{
get { return !Task.IsCompleted; }
}
public bool IsSuccessfullyCompleted
{
get
{
return Task.Status ==
TaskStatus.RanToCompletion;
}
}
public bool IsCanceled
{
get { return Task.IsCanceled; }
}
public bool IsFaulted
{
get { return Task.IsFaulted; }
}
public AggregateException Exception
{
get { return Task.Exception; }
}
public Exception InnerException
{
get
{
return (Exception == null)
? null
: Exception.InnerException;
}
}
public string ErrorMessage
{
get
{
return (InnerException == null)
? null
: InnerException.Message;
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
【问题讨论】:
-
因为它很可能在绑定设置之前完成。
标签: c# .net mvvm async-await