This is a sample .xaml code that I have, I'm using DrawerHost
Control from MaterialDesignInXamlToolkit
<UserControl
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignInstance viewModels:UserControlViewModel}"
mc:Ignorable="d"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes">
<materialDesign:DrawerHost IsRightDrawerOpen="{Binding IsDrawerOpen}" OpenMode="Default">
<materialDesign:DrawerHost.RightDrawerContent>
<views:RightDrawerView />
</materialDesign:DrawerHost.RightDrawerContent>
<!-- Main Content -->
</materialDesign:DrawerHost>
</UserControl>
RightDrawerViewModel
will be set to be the DataContext of RightDrawerView
via Prism's ViewModelLocationProvider
.
My Question: When setting IsDrawerOpen
to true, how can UserControlViewModel
pass parameters to RightDrawerViewModel
? as RightDrawerViewModel
is not called via Prism's methods (regionManager?.RequestNavigate
, dialogService?.ShowDialog
).
CodePudding user response:
If you want to pass parameters, you can either RequestNavigate
instead of setting IsDrawerOpen
(which needs a region and an custom RegionAdapter
for the DrawerHost
) or you create a service known to both the view model that wants to open the drawer and the drawer's view model and put all data there before setting IsDrawerOpen
.
A third option is to create a new DrawerViewModel
when you want to open the drawer and assign it to a property on the parent view model and bind it to the drawer's content's data context. Also, remove IsDrawerOpen
and replace it either with a style or a converter that observe the view model-property on the parent.
I'd go for the first option only if I were forced to go view first, otherwise always prefer the third one. The second's ugly and presented for completeness only.
CodePudding user response:
My Solution..
- First, Define
NavigationParameters
property inRightDrawerViewModel
public class RightDrawerViewModel {
public NavigationParameters NavigationParameters { set; get; }
}
In my case, I have predefined BaseViewModel
that implements INavigationAware
, so I've added NavigationParameters property to it (this way I can hold the parameters that are passed via RequestNavigate
even for other ViewModels that inherit from BaseViewModel
and use this property for the rest of the OnNavigatedTo
code)
public class RightDrawerViewModel : BaseViewModel {
// ..
}
public abstract class BaseViewModel : INavigationAware {
public NavigationParameters NavigationParameters { set; get; } // parameters holder
public void OnNavigatedTo(NavigationContext navigationContext)
{
if (navigationContext?.Parameters != null)
NavigationParameters = navigationContext.Parameters;
// ..
}
public void OnNavigatedFrom(NavigationContext navigationContext)
{
NavigationParameters = null;
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
// ..
}
- Then, Pass the parameters before setting
IsDrawerOpen
to true..
// 1. Let UserControl class implement an interface that has `DataContext GetRightDrawerDataContext();` method,
// 2. Inject services instnace in ctor of UserControlViewModel via Prism's Ioc Container
if (services.GetRightDrawerDataContext() is INavigationAware nv)
nv.NavigationParameters = parameters; // parameters to pass
IsDrawerOpen = true;
- Finally,
RightDrawerViewModel
can get the parameters fromNavigationParameters
property.
var b = NavigationParameters?.TryGetValue("Parameter1Key", out object object1Instance);