2016-08-19 8 views
0

こんにちはすべて(私はフランス語です)、 私のコードに少し問題があります。私はMVVMを実装しようとしましたが、私の接続が非同期で開き、バインドするオブジェクトのリストを取得してSQLReaderに戻りますが、バインディングがGUIでリフレッシュされていないため、ASYNC関数がプログラムを間違ってしまいます。私はMVVMシステムでは本当に新しいので、私は何かが間違っていると確信しています。MVVM ASYNC GUI SLQ接続

ここに私のコード(申し訳ありませんが、テキストのハイライトを見つけたことができます):

する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); 
      } 
     } 
    } 
} 

誰でも私の問題についてのヒント、アドバイス、または解決策を教えてください。私は(かなりsur not)はっきりした男だといいです。

ありがとうございます。

答えて

0

私が正しく理解しているのは、ユーザーコントロールの起動時にVM内のデータを非同期で初期化することです。コンストラクタは非同期にすることはできません。そのため、非同期呼び出しを行うことはできません。

この問題を回避する方法の1つは、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(); 
    } 
} 

これはasynchrouslyとすぐに、ユーザーコントロールは、そのコンテンツをロード行われるようにデータをロード。

編集:既に初期化機能が別になっているため、公開するだけでイベントにフックするだけです。 また、非同期関数の戻り値としてvoidを使用しないでください。タスクを代わりに使用してください。here's why

+0

ありがとうございます。私は悲しいことにはっきりしていないと思います。問題は自分のGUIです。私のデータバインディングのソースが変更された場合、私のコントロールのコンテンツは更新されません... – PrivHateVoid

+0

ああ、おそらくINotifyPropertyChangedはあなたが探しているものにすることができますか?これは、基本的に、あなたのVMに何かが変わったことをGUIに伝える方法です。 https://msdn.microsoft.com/en-us/library/ms743695(v=vs.110).aspx – Hogler

関連する問題