我的代码是随机在线教程和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] 举报,一经查实,本站将立刻删除。