4

WinForm から WPF ウィンドウにデータを渡し、WPF ウィンドウからメッセージを受信しようとしています。

私のコードは、ランダムなオンライン チュートリアルと HighCore のログ ビューアーを組み合わせたものです。次の方法で新しい WPF ウィンドウを起動する WinForm があります。

private void openTransactionViewToolStripMenuItem_Click(object sender, EventArgs e)
  {
     var transactionViewWindow = new TransactionViewer.MainWindow();
     ElementHost.EnableModelessKeyboardInterop(transactionViewWindow);
     transactionViewWindow.Show();
     transactionViewWindow.Test = "test";   // testing out data passing
     transactionViewWindow.AddTest();
  }

私の MainWindow.xaml.cs は次のようになります。

public partial class MainWindow : Window
{
  public ObservableCollection<Session> SessionList { get; set; }
  public string Test{ get; set; }

  public MainWindow()
  {
     InitializeComponent();

     SessionList = new ObservableCollection<Session>();

     SessionList.Add(new Session() { BeginLine = 0, EndLine = 1, Message = "some message" });
     SessionList.Add(new Session() { BeginLine = 2, EndLine = 3, Message = "another message" });

     SessionItems.ItemsSource = SessionList;  // the ItemsControl
  }

  public void AddTest()
  {
     SessionList.Add(new Session() { BeginLine = 4, EndLine = 5, Message = Test });
  }
}

public class Session : PropertyChangedBase
{
   public int BeginLine { get; set; }
   public int EndLine { get; set; }
   public string Message { get; set; }
}

どこPropertyChangedBaseから継承しINotifyPropertyChangedます。にバインドされた ItemsControl がありMessageます。私の出力は次のようになります。

いくつかのメッセージ
別のメッセージ
テスト

「データ受け渡し」成功!List<Session>最終的に、WPF ウィンドウが読み込まれるときに、ItemsControl を設定するために使用される WinForm からを渡したいと思います。また、リストを送信してWPFのデータを再入力/更新するボタンをWinFormに配置したいと考えています。現在の動作から、これは現在の単純な実装 (更新のみ) でも可能であると思いますSessionList

これを行うより適切な方法はありますか?例えばイベント?WPF がすべてのオブジェクトを正常に追加したことを WinForm に伝えるためにSession、またはユーザーが特定のオブジェクトをクリックするたびに、イベントを発生させる必要がありますか?
ここでMVVMを使用する利点はありますか?

私はしばらくの間、WinForms 向けに開発を行ってきましたが、WPF への移行が非常に混乱していることに気づきました。誰かがガイダンスやコード例を手伝ってくれることを願っています。

編集: 今後の参考のために、私のような人々を対象とした適切な MVVM チュートリアルをここで見つけることができます: http://jpreecedev.com/2013/06/08/wpf-mvvm-for-winforms-devs-part-1-of- 5/

4

1 に答える 1

1

あなたのアプローチは私にはOKのようです。完璧ではありませんが、十分に機能します。

Window最適なアプローチである IMO は、データをやり取りするときにそれ自体を直接参照するのではなく、WPF ウィンドウの ViewModel を作成することです。

アイデアは次のとおりです。

public class MyForm: Form
{
   public TransactionViewerViewModel TransactionViewer {get;set;}

   //... other code...

   //Form constructor:
   public MyForm()
   {
       InitializeComponent();

      //Create ViewModel:
      TransactionViewer = new TransactionViewerViewModel();
   }

   private void openTransactionViewToolStripMenuItem_Click(object sender, EventArgs e)
   {
      //Create WPF View:
      var transactionViewWindow = new TransactionViewer.MainWindow();

      //Interop code
      ElementHost.EnableModelessKeyboardInterop(transactionViewWindow);

      //Set DataContext:
      transactionViewWindow.DataContext = TransactionViewer;     

      //Show Window:
      transactionViewWindow.Show();

      //Call methods on the ViewModel, rather than the View:
      TransactionViewer.Test = "test";   // testing out data passing
      TransactionViewer.AddTest();
   }
}

したがって、ViewModel は次のようになります。

public class TransactionViewerViewModel : PropertyChangedBase
{
  public ObservableCollection<Session> SessionList { get; set; }
  public string Test{ get; set; }

  public TransactionViewerViewModel()
  {
     SessionList = new ObservableCollection<Session>();

     SessionList.Add(new Session() { BeginLine = 0, EndLine = 1, Message = "some message" });
     SessionList.Add(new Session() { BeginLine = 2, EndLine = 3, Message = "another message" });

  }

  public void AddTest()
  {
     SessionList.Add(new Session() { BeginLine = 4, EndLine = 5, Message = Test });
  }
}

これにより、ViewModel の単体テストを作成できるようになるまで、WPF UI と実際のデータ/ビジネス ロジックが完全に分離されます。

また、ViewModel を Window の として設定しているためDataContext、手続き型コードではなく、DataBinding を介してすべての ViewModel プロパティにアクセスする必要があります。

<ItemsControl ItemsSource="{Binding SessionList}"/>

次に、 ViewModel にdelegatesorを導入し、Form でこれらをリッスンして、コミュニケーションを実現することができます。eventsWPF => winforms

于 2013-11-15T02:09:17.307 に答える