I have a parent window that loads a usercontrol inside a ContentControl. The parent window has a ToolBar with some buttons (i.e. Save button). I'd like to assign those buttons commands that would be handled inside the usercontrol.
I need to manage my own ICommand commands from the usercontrol's ViewModel so, to summarize: The user clicks on the "Save" button (on the main window) so the button fires an event which the userControl h开发者_Python百科andles to save the information within the control.
Is this possible?
There are two ways of doing it.
Using MVVM,
Since your window contains UserControl, you need to set up so that Window has reference to the UserControl ViewModel(assume it is called UserControlViewModel). If you have a command in the UserControlViewModel, you could bind to that command, by calling: UserControlViewModel.Command something like:<Button x:Name="Save" Content="Save" Command="{Binding UserControlViewModel.SaveCommand}">
Use the event handler
Again, your window needs to have a reference to the class where the event handler is implemented. you could have the following in your Window XAML file:
<Button x:Name="Save" Content="Save" Clicked="SaveButtonClicked"/>
Then in your code behind,
private void SaveButtonClicked( .... sender, .... e) { UserControlClass.SaveData(); // or using command UserControlClass.MyCommand.Execute() }
OK, you are trying to bind a child element's command to a parent window. First give a name to the usercontrol (e.g. x:Name = MyUserControl) and write a public command in the usercontrol's datacontext/viewmodel (e.g. ICommand MyCommand). Now in the button do this
<Button x:Name="SaveButton" Command={Binding ElementName=MyUserControl, Path=DataContext.MyCommand} />
This will bind the save buttons command to the command inside the datacontext of child usercontrol :)
BTW, if you are looking for the other way around (i.e. binding child command to parent in mvvm) you will need to use FindAncestor. You can have a look on my codeproject article regarding this :)
This sounds like a case where Routed Commands could work. For the routed command, set the Command of the tollbar button to "Save". Then in the user control, add a command binding that listens for the "save" command.
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.CommandBindings>
<CommandBinding
Command="Save"
CanExecute="SaveCommand_CanExecute"
Executed="SaveCommand_Executed"
/>
</UserControl.CommandBindings>
</UserControl>
In the code-behind's event handlers for the command binding, just locate the viewmodel and invoke the save command on it's viewmodel. If you want a more purist MVVM approach, you could try Josh Smith's approach to routed commands with MVVM.
Using this approach, as long as the user control has focus somewhere inside of it, then the save button's Save command will route to the user control's command binding and exec the save command.
I think this might accomplish your goal of decoupling the toolbar button from the dynamically loaded user control in the ContentPresenter.
Well after a while I come back to this question. I needed to communicate with my parent window so i decided to perform the view-viewmodel datacontext binding right from the parent window, mainly because I want the child viewmodel to attach to events fired from its parent and also I can fire events to the parent in order to show messages outside the child control.
I know I may not be using the MVVM pattern completly but I wanted to have more control over these features.
精彩评论