用户控件作为组件.无法访问父窗口 [英] User Control as components. No access to Parent Window
问题描述
我正在学习 WPF 和 MVVM 模式,但我可能会错误地实现.
I am learning WPF and the MVVM pattern, and I may be implementing things incorrectly.
我想使用用户控制对象为我的应用程序窗口构建组件,其中组件可以跨 Windows 使用.例如,我有一个 NewUnitUserControl,我打算将它用作对话框窗口的唯一组件,也用作 MainWindow 的组件.
I want to build out components for my app's windows using User Control objects, where components could be used across Windows. For an example I have a NewUnitUserControl that I intend to use as the only component for a dialog window, and also as a component for the MainWindow.
NewUnitUserControl.xaml:
NewUnitUserControl.xaml:
<UserControl x:Class="Sample.Views.UserControls.NewUnitUserControl"
...
xmlns:local="clr-namespace:Sample.Views.UserControls">
<Grid>
<StackPanel Orientation="Vertical">
<Border>
<StackPanel Orientation="Horizontal">
<Label>Name:</Label>
<TextBox Text="{Binding Unit.Name}" Width="136"/>
</StackPanel>
</Border>
<Border HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal">
<Border>
<Button Command="{Binding CreateUnitCommand}">Create</Button>
</Border>
<Border>
<Button Command="{Binding CancelCommand}">Cancel</Button>
</Border>
</StackPanel>
</Border>
</StackPanel>
</Grid>
</UserControl>
NewUnitUserControl.xaml.cs:
NewUnitUserControl.xaml.cs:
namespace Sample.Views.UserControls
{
public partial class NewUnitUserControl : UserControl
{
public NewUnitUserControl()
{
InitializeComponent();
NewUnitViewModel nuvm = new NewUnitViewModel();
DataContext = nuvm;
if (nuvm.CloseAction == null)
{
var window = Window.GetWindow(this); // window evaluates to null
// after this line.
nuvm.CloseAction = new Action(window.Close);
}
}
}
}
NewUnitViewModel.cs
NewUnitViewModel.cs
namespace Sample.ViewModels
{
internal class NewUnitViewModel : INotifyPropertyChanged
{
//Properties
private Unit _unit;
public Unit Unit
{
get { return _unit; }
set { _unit = value; OnPropertyChanged("Unit"); }
}
public Action CloseAction { get; set; }
private ICommand _createUnitCommand;
public ICommand CreateUnitCommand
{
get
{
if (_unitUpdateCommand == null)
_unitUpdateCommand = new RelayCommand(param => CreateUnit(), param => true);
return _unitUpdateCommand;
}
}
private ICommand _cancelCommand;
public ICommand CancelCommand
{
get
{
if(_cancelCommand == null)
_cancelCommand = new RelayCommand(param => Cancel(), param => true);
return _cancelCommand;
}
}
//Constructor
public CreateUnitViewModel()
{
_unit = new Models.Unit();
}
//Methods
public void CreateUnit()
{
Debug.Assert(false, String.Format("{0} was created.", Unit.Name));
}
public void Cancel()
{
this.CloseAction();
}
#region INotifyProperty Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
NewUnitDialogWindow.xaml:
NewUnitDialogWindow.xaml:
<Window x:Class="Sample.Views.NewUnitWindow"
...
xmlns:local="clr-namespace:Sample.Views"
xmlns:controls="clr-namespace:Sample.Views.UserControls"
>
<controls:NewUnitUserControl />
</Window>
NewUnitDialogWindow.xaml.cs
NewUnitDialogWindow.xaml.cs
namespace Sample.Views
{
public partial class NewUnitWindow : Window
{
public NewUnitWindow()
{
InitializeComponent();
}
}
}
完整来源:GitHub
我立即面临的问题是,在我的实现中,我无法使用解决方案访问用户控件的父窗口 此处(请参阅 NewUnitUserControl.xaml.cs 中的注释).我希望我的问题的根源在于我没有正确理解 MVVM 模式.
The problem I'm immediately facing is that with my implementation, I'm unable to access the User Control's parent window using the solution here (see the comment in NewUnitUserControl.xaml.cs). I expect the root of my issues is that I'm not understanding the MVVM pattern correctly.
推荐答案
我认为问题是用户控件还不知道父窗口是谁.尝试转到 Loaded 事件:
I think the problem is that the user control doesn't know who the parent window is yet. Try moving to the Loaded event:
private Window _parentWindow = null;
public NewUnitUserControl()
{
InitializeComponent();
Loaded += (s, e) =>
{
_parentWindow = Window.GetWindow(this);
/// whatever you are going to do with parent window
}
}
您还可以使用 Prism 工具包中的 IEventAggregator 或 MvvmToolkit 中的 IMessenger(我认为这就是它的名字)之类的东西从按钮的命令操作发送消息.
You could also send a message from the button's command action using something like IEventAggregator from the Prism toolkit or IMessenger (I think that is what it is called) from MvvmToolkit.
这篇关于用户控件作为组件.无法访问父窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!