我有选择对象DataGrid,其行选择已更改在方法中处理(使用交互事件触发器InvokeCommandAction)。一行代表一个真实的生活对象,并且有很多属性。
我首先设置一个属性,该行对应并在地图上突出显示对象,执行其他操作,最后调用异步方法获取对象属性并使用这些属性刷新属性DataGrid。
SelectedObjectsViewModel.cs(包含SelectedObjects DataGrid的UserControl的Viewmodel)
public void SelectedObjectsGridSelectionChangedCommand(object parameter)
{
IList selectedRows = parameter as IList;
if (selectedRows.Count == 1)
ObjectProperties.Instance.SetAttributeObjectNoRefresh(((SelectedNetObjectBindingSource)selectedRows[0]).Data);
else
ObjectProperties.Instance.SetAttributeObjectNoRefresh(null);
SetAttributeObjectExtraHightlight<SelectedNetObjectBindingSource>(selectedRows);
DoSomeOtherStuff(selectedRows)
App.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
{
((ObjectViewModel)MyApp.ViewModels["Shared.Panels.Object"]).SelectedObjectsChanged();
}));
}
ObjectViewModel.cs(包含Properties DataGrid的UserControl的Viewmodel)
// this is ItemsSource binding for properties datagrid
public ICollectionView ObjectInfoItems { get; private set; }
public ObjectViewModel()
{
ObjectInfoItems = CollectionViewSource.GetDefaultView(ObjectProperties.Instance.GetAttributeObjectAttributes());
}
public void SelectedObjectsChanged()
{
// refreshed DataGrid
ObjectInfoItems.Refresh();
}
ObjectProperties.cs
public void SetAttributeObjectNoRefresh(NetObject netObject)
{
_attributeObject = netObject;
}
public IEnumerable<PropertyRow> GetAttributeObjectAttributes()
{
if (_attributeObject != null)
{
List<string> fieldNames = new List<string>();
List<string> visibleNames = new List<string>();
List<string> values = new List<string>();
/* get properties for _attributeObject from db and
* process in native code */
var properties = GetPropertiesFilterAndSort(fieldNames, visibleNames, values, _attributeObject);
foreach (var property in properties)
{
yield return property;
}
}
}
然而,在完成其他所有内容(如突出显示)之后,包含对象属性的DataGrid最多会延迟1,2秒。我想立即开始获取我知道对象,继续突出显示等,最后异步启动SelectedObjectsChanged以使用fetched属性数据来刷新DataGrid。
提取涉及数据库提取和一些处理。根据具体情况和设置,数据库获取时间最多可达80%,但可能只有50%。
我的问题是:如何做到这一点:
谢谢!
答案 0 :(得分:3)
您应该在后台线程上执行任何长时间运行的方法。请注意,您无法访问后台线程上的任何UI元素,因此您基本上需要启动一个新任务来获取数据,然后在任务完成后处理任何UI内容。
以下是在后台线程上执行GetAttributeObjectAttributes()
方法的基本示例:
private ICollectionView _ojectInfoItems;
public ICollectionView ObjectInfoItems
{
get { return myVar; }
set { myVar = value; OnPropertyChanged(); }
}
public ObjectViewModel()
{
Task.Factory.StartNew(() =>
{
return ObjectProperties.Instance.GetAttributeObjectAttributes();
}).ContinueWith(task =>
{
ObjectInfoItems = CollectionViewSource.GetDefaultView(task.Result);
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
请注意,ObjectViewModel
类应实现INotifyPropertyChanged接口,并在设置数据绑定PropertyChanged
属性时引发ObjectInfoItems
事件。
修改强>
基于您的评论的另一个例子:
public void SelectedObjectsGridSelectionChangedCommand(object parameter)
{
object data = null;
IList selectedRows = parameter as IList;
if (selectedRows.Count == 1)
data = (SelectedNetObjectBindingSource)selectedRows[0]).Data;
Task.Factory.StartNew(() =>
{
ObjectProperties.Instance.SetAttributeObjectNoRefresh(null);
Parallel.Invoke(
() => SetAttributeObjectExtraHightlight<SelectedNetObjectBindingSource>(selectedRows),
() => DoSomeOtherStuff(selectedRows));
}).ContinueWith(task =>
{
((ObjectViewModel)MyApp.ViewModels["Shared.Panels.Object"]).SelectedObjectsChanged();
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}