从ViewModel中打开一个窗口窗体
本文关键字:一个 窗口 窗体 ViewModel | 更新日期: 2023-09-27 18:16:34
我正在开发一个遗留产品,到目前为止,它的所有内容都是使用windows窗体制作的。由于需要大量使用xml,所以我使用WPF,因为它易于绑定。我正在使用MVVM模型,因为需求需要不同的视图,但业务逻辑没有太大差异。我有一个用户控件,它有一个打开windows窗体的按钮。这个用户控件在不同的windows窗体上。
这是我的xaml与按钮相关的代码:
<UserControl x:Name="ctrlTemplate" x:Class= "CtrlTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFControl.UI"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:xckt="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
mc:Ignorable="d"
DataContext="{DynamicResource ViewModel}">
<UserControl.Resources>
<local:ViewModel x:Key="ViewModel" />
</ResourceDictionary>
</UserControl.Resources>
下面是与
按钮绑定的命令<Button x:Name="btnOpenWindowsUI" Command="{Binding OpenWindowsUI, Source={StaticResource ViewModel}}" CommandParameter={????} >
我的ViewModel是这样的
public class ViewModel : ViewModelBase
{
public ICommand OpenWindowsUI{ get; set; }
public OTCViewModel()
{
OpenWindowsUI= new OpenWindowsUI(this);
}
}
我的命令是这样的:
class OpenWindowsUI: ICommand
{
private ViewModel _mvModel;
public event EventHandler CanExecuteChanged
{
add { }
remove { }
}
public ClearAllData(ViewModel mvModel)
{
_mvModel = mvModel;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
IWindowsUI indowsUIInstance = null;
windowsUIInstance = _container.Resolve<IWindowsUI >();
frmWindowsUI = windowsUIInstance.Reference();
frmWindowsUI.Owner = this; **//How can we specify the parent of this chid form?**
frmWindowsUI.ShowInTaskbar = false;
windowsUIInstance.SetUp();
frmWindowsUI.Show();
frmWindowsUI.FormClosed += frmWindowsUI_FormClosed;
}
}
我知道可以很容易地从usercontrol代码中找到父窗体,使用下面的代码片段:
public Form FindParentWindowsForm()
{
var source = (HwndSource)PresentationSource.FromDependencyObject(btnOpenWindowsUI);
Form form;
if (source != null)
{
var host = (System.Windows.Forms.Integration.ElementHost)System.Windows.Forms.Control.FromChildHandle(source.Handle);
if (host != null)
{
form = (Form)host.TopLevelControl;
}
}
return form;
}
我的问题是:
是否有一种方法将UI元素从控件传递到ViewModel?
我们应该把一个UI元素的引用传递给ViewModel吗?
如果不是,解决上述问题的最佳方法是什么?
我没有完整的解决方案。
。1。是的,你可以-例如下面的代码将传递整个窗口对象作为CommandParameter:
<button [...] CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"/>
。2。这个问题是典型的MVVM辩论的主题。一方面,UIElement只是一个对象,它在高级视图中与其他对象(如属性)没有真正的不同,但另一方面,传递UIElement作为参数有点破坏MVVM,因为从这一刻起ViewModel将意识到视图。
。3。
- 。你不应该把UI元素传递给MVVM中的ViewModel。
- 您可以创建一个单独的控件并将其绑定到视图。在控件中创建一些依赖属性。通过ViewModel更改属性的值。当你可以改变这个值时,控件就会被调用依赖属性,现在窗口中就有了控件的可视树。
请参考http://social.technet.microsoft.com/wiki/contents/articles/31416.wpf-mvvm-friendly-user-notification.aspx#ConfirmationRequestor