大家好(提前抱歉我是法国人), 我的代码有点问题。我尝试实现MVVM但我的ASYNC函数使我的程序错误,因为他打开我的连接异步,获取绑定对象列表(So null)并返回SQLReader但是为时已晚我的绑定不在GUI中刷新。我是MVVM系统的新手,所以我肯定会错过一些东西。
我的代码在这里(抱歉可以找到文字突出显示):
DataBinding XAML:
<UserControl.DataContext>
<local:UcGridViewModel/>
</UserControl.DataContext>
这里是ViewModel类:
namespace *******.ViewModel
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Linq;
using Newtonsoft.Json;
using DataObject;
using DevExpress.Mvvm;
public class UcGridViewModel : BindableBase
{
public UcGridViewModel()
{
this.InitaliseTreeViewDatacontext();
}
IEnumerable<TreeItem> treeItemDataBinding;
public IEnumerable<TreeItem> TreeItemDataBinding
{
get
{
return this.GetProperty(()=> this.treeItemDataBinding);
}
}
private async void InitaliseTreeViewDatacontext()
{
var listProprieteAscDesc = new ObservableCollection<Dictionary<string, string>>();
var conn = DataAccess.GetSqlconnection();
var jsonContextLocal = "\"*******\" : 2";
jsonContextLocal += "\"*******\" : \"True\"";
var sqlCmd = new SqlCommand("SELECT JSON FROM *******(" +
ApplicationContext.GetsimplifiedStringJsonContext(jsonContextLocal), conn);
using (conn)
{
await conn.OpenAsync();
var result = await sqlCmd.ExecuteReaderAsync();
var pastFirstRow = false;
while (await result.ReadAsync())
{
if (!pastFirstRow)
{
pastFirstRow = true;
continue;
}
var json = result.GetString(0);
var deserializedObject = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
listProprieteAscDesc.Add(deserializedObject);
}
}
this.treeItemDataBinding = listProprieteAscDesc.Select
(
d => new TreeItem(d["*******"], d["*******"], d["*******"])
);
}
}
}
这是我的对象:
namespace *******.DataObject
{
using DevExpress.Mvvm;
public class TreeItem : BindableBase
{
public TreeItem(string label, string parent, string id)
{
this.Label = label;
this.Parent = parent;
this.Id = id;
}
public string Label
{
get
{
return this.GetProperty(() => this.Label);
}
private set
{
this.SetProperty(() => this.Label, value);
}
}
public string Parent
{
get
{
return this.GetProperty(() => this.Parent);
}
private set
{
this.SetProperty(() => this.Parent, value);
}
}
public string Id
{
get
{
return this.GetProperty(() => this.Id);
}
private set
{
this.SetProperty(() => this.Id, value);
}
}
}
}
请有人能就我的问题向我提供一些提示,建议或解决方案吗?我希望(非常不是)很清楚。
提前谢谢。
答案 0 :(得分:0)
如果我理解正确,目标是在用户控件启动时异步初始化VM中的数据。构造函数不能同步,因此您无法在其中进行异步调用。
解决此问题的一种方法是在VM中使用单独的InitializeAsync()函数并将其挂接到用户控件的Loaded事件。 VM部分看起来像这样:
public class MyViewModel
{
protected async Task InitializeAsync()
{
// Do async stuff here
}
}
然后在用户控件的.cs中:
public partial class MyControl
{
public MyControl()
{
Loaded += async (s, e) => await ((MyViewModel)DataContext).InitializeAsync();
}
}
只要用户控件加载完其内容,就会异步加载数据。
编辑:您已经将Initialize功能分开,所以您只需将其公开并将其挂钩即可。 此外,您应该避免作为异步函数的返回类型的void。请改为使用任务here's why。