2016-10-05 10 views
2

私はC#/ WPF/Entity Framework DBに、まずクーラントラインからのフローや温度などの値を測定する独自の産業用ハードウェアと通信するアプリケーションを作成しています。これらの値は、バックグラウンドで実行されるスレッドでSQL Serverデータベース内で頻繁に更新され、UIに表示されます。データベースの変更としてWPF UIを更新する方法

私の懸念は、現在、私がこれらの変更を反映するためにUIを更新する方法です。私は私のviewmodelに私のDataContextを設定

、および毎秒実行するスレッドをインスタンス化します:ここで私はデータグリッドを更新する方法の例です

_DataContext = new ViewModels.SummaryTable_ViewModel(); 
    this.DataContext = _DataContext; 
    UIUpdateThread = new Thread(UIUpdaterThread); 
    UIUpdateThread.IsBackground = true; 
    UIUpdateThread.Start();  

私のグリッドのベースとなるモデルはIListの<です>それは次のようになります。

private IList<channel> _channel; 
    public IList<channel> Channels 
    { 
     get 
     { 
      return _channel; 
     } 
     set 
     { 
      _channel = value; 
      //NotifyPropertyChanged(); 
      OnPropertyChanged("Channels"); 
     } 
    } 

が続い毎秒私UIUpdateThreadは、以下のようになる()メソッド私のFillChannelsを呼び出し、その後のPropertyChanged通知に基づいて、グリッドの更新:

using (var DTE = new myEntities()) 
      { 
       if (DTE.channels.Any()) 
       { 
        var q = (from a in DTE.channels 
          where a.setup.CurrentSetup == true 
          orderby a.ChannelNumber 
          select a).ToList(); 

        this.Channels = q; 
       } 
      } 

私の質問はこれです:これを行うには、より良い、よりエレガントな方法はありますか?これはより良い言葉の欠如のために "間違っている"と感じます。また、スレッドが実行されるたびに、データグリッドでユーザー設定のソートをリセットするなど、悪い副作用があります。また、私はそれがMVVMのパターンを破ると思うが、私は確信していない。

たとえば、私のハードウェアと通信しているスレッドがデータのハードウェアをポーリングするたびにShared Channelオブジェクトを更新し、UIをバインドするだけではこのスレッド(または同じことをする他のUIの他のスレッド)を実行し、PropertyChanged通知に基づいて更新するだけです。または、私が完全に気付いていない他の方法がいくつかありますか?答えを探しているとき、私にはわかりませんが、仕事パターンの単元がここに関連する概念であることがわかりました。

ここからわかるように、私はここからどこに行くべきかについてはあまりよく分かりません。テキストの壁には申し訳ありませんが、できるだけ徹底したかっただけです。どんな支援も大歓迎です。ありがとう。

+1

私は、 'Channels'を' ObservableCollection'にしてから始めましょう。アイテムが追加または削除された場合は、コレクションを再作成する代わりにアイテムを追加/削除します。一般的に、2番目から最後の段落はお金の上にあります:適切な変更通知を提起する既存のものを変更する。新しい現在の状態全体にぴったりと並んでいることに比べてちょっと絡まってしまいますが、もしそれをする必要があれば、それをする必要があります。 P.S .: rory.apが言ったこと。 –

+0

ヘルプありがとうございます@EdPlunkett – user3900520

答えて

4

あなたのモデルは、新しいデータがあるときにあなたのビューモデルに通知するモデルである必要があります。あなたはこれを達成するメカニズム(私があなたが使用していると思うタイマーのようなもの)をモデルに入れるべきです。

基本的に、モデルはビューモデルに通知し、ビューモデルはデータ変更があることをビューに通知します。ビューを正しく設定し、コードビハインドではなくXAMLを使用する場合は、ビューとビューモデル間のデータバインディングを介して自動的に一緒に表示されます。

並べ替えに関して:ビューのグリッドの並べ替えプロパティにバインドされたビューモデルの別のプロパティである必要があります。モデルは、データが変更されたときにビューモデルに通知する前に、ユーザー設定のソートを維持し、更新されたデータに適切に適用する必要があります。

データの関連する行を複数の表に永続化し、1つのトランザクション(データを読み取るだけの場合)にすることについて話しているわけではないので、作業単位をここに適用できるかどうかはわかりません。私は仕事の単位をそれほど研究していないので、間違っている可能性があります。


はコメントでご質問に対処するには、次の

は背中のステップを見てみましょう。あなたのビューモデルはのみ関連するビューの表示に関連するロジックに関係する必要があります。ビジネスロジックやドメイン関連のタスクを実行するデータアクセスコードやコードは使用しないでください。そのコードは集合的に "モデル"と呼ばれるものに入ります(あなたがすでにこれを持っているなら私を許してください。しかし、あなたがあなたの質問で提供したコードがどこにあるのかを正確に伝えるのは難しい)。

モデルは、さまざまなビジネスロジックタスクを実行するか、ドメイン/エンティティPOCO(エンティティフレームワーク生成クラスなど)を表す多くのクラスで構成できます。

あなたのChannelオブジェクトが何であるか、エンティティクラス/ POCO、つまりEF生成モデルとはどのように離れているかは少し不明です。しかし、やはりEFとのやりとりやエンティティに関連するメンテナンスやロジックがモデル内で起こるはずです。

そうですね、どのような仕組みを使用してもモデルのデータ変更を探すという考えがあります。タイマー(btwには同期して動作するタイマーがありますので、「タイマー」という概念を「スレッド」とコンバートしないでください)、エンティティーのコレクションの「コレクション変更」イベントに直接バインドしないでください。変更が検出されたら、モデルの変更に必要なビジネスロジック(変換、並べ替え、ログなどの適用)を行い、変更が発生したことをビューモデルに通知するだけです。

+0

まず、助けてくれてありがとう。このインスタンスで私のモデルは何ですか? Entity Frameworkによって自動的に生成されたモデルですか?もしそうなら、私はCodeFirstに変換する必要があるので、それらを変更することができますか?それとも、私がビューモデルに持っているChannelオブジェクトですか?私が今やっているようにデータベースを毎回照会するスレッドをモデルに入れ、直接バインドするという考えはありますか? CollectionChangedイベントが発生するため、UIが更新されますか? (私が必要とするのは、あなたのコレクションが編集された/削除されたものよりも多いからです。 – user3900520

+0

@ rory.apのバグに気をつけない - 私はこの1つ上のコメントで私の質問を編集しました。私はモデルを更新する必要があるかどうかについては、私がモデルをどういう意味か、私はこれを理解することに非常に近いと思います。どちらかといえば、もう一度感謝します。 – user3900520

+1

@ user3900520 - 問題ありません。私の更新を見てください。 –

関連する問題