微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 将数据从WinForm传递到WPF

我希望从WinForm将数据传递到 WPF窗口,并从 WPF窗口接收消息.

我的代码随机在线教程和HighCore的log viewer的混合.我有一个WinForm以下列方式启动我的新WPF窗口:

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.我的输出看起来像:

some message
another message
test

“数据传递”成功!最后,当WPF窗口加载时,我想传递List< Session>从我的WinForm将用于填充ItemsControl.我还想在WinForm上有一个按钮,它将发送一个List来重新填充/刷新WPF中的数据.从目前的行为来看,我认为即使使用我当前的简单实现(只是更新SessionList),这也是可能的.

有没有更合适的方法呢?事件,例如?我是否需要触发一个事件以告诉我的WinForm WPF已成功添加所有Session对象,或者每当用户点击特定对象时?
在这里使用MVVM有什么好处?

我已经为WinForms开发了一段时间,并且发现转换到WPF非常混乱.希望有人可以提供一些指导或代码示例.

编辑:为了将来参考,可以在这里找到针对像我这样的人的体面的MVVM教程:http://jpreecedev.com/2013/06/08/wpf-mvvm-for-winforms-devs-part-1-of-5/

解决方法

你的方法对我来说似乎没问题.它并不完美,但它足够可行.

最佳方法IMO将为WPF窗口创建viewmodel,而不是在来回传递数据时直接引用Window本身.

这个想法是:

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,Message = "another message" });

  }

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

这实现了WPF UI与实际数据/业务逻辑之间的完美分离,甚至可以为viewmodel创建单元测试.

而且,由于您将viewmodel设置为Window的DataContext,因此您需要通过DataBinding访问所有viewmodel属性,而不是过程代码

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

然后,您可能希望在viewmodel中引入委托或事件,并在您的表单中听取这些,从而实现WPF => winforms沟通.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐