I have a custom usercontrol (ChartControl
) that I use within my WPF app (MainApp
) and which I render as follows:
<ContentControl Grid.Row="1" Content="{Binding ChartControl, Mode=OneWay}" />
Upon starting MainApp
the following are executed in the given order:
MainApp View MainApp ViewModel ChartControl ViewModel ChartControl View
I instantiate the ChartControl
ViewModel from within the constructor of my MainApp
ViewModel. The problem is that after instantiating the ChartControl
ViewModel I also need to call a method of ChartControl
from within MainApp
.
The problem I am having is that I need the ChartControl
view to be rendered (have its InitializeComponent
executed) before I call the method as part of its viewmodel.
I thought one solution could be to notify the view model from the view when it is fully instantiated and set up. Is that a viable solution and if yes how would I do that?
In summary, I need the view to be fully set up before invoking a method of the matching viewmodel. The problem I am having is that in this case the view model is instantiated first and only then is the view rendered.
Any ideas?
Thanks
You can make use of Interactivity triggers to fire Command on your VM on any UI event
You can listen to Loaded event of UserControl like below and bind it to Command on your VM:
<UserControl x:Class="Test.TestView.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
x:Name="myControl" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding ElementName=myControl, Path=OnLoadedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
And sure you will have Command in your VM as
public ICommand OnLoadedCommand { get; private set; }
public MyUserControl()
{
OnLoadedCommand = new DelegateCommand(OnLoaded);
}
public void OnLoaded()
{
}
Another way to hook up the Loaded event, basically rendering the same result as nit's answer, is simply referencing your viewmodel in the constructor of the view and adding an event handler which in turn calls whatever method you need to call, like this:
public MyControl()
{
InitializeComponent();
this.Loaded += (s, e) => { ((MyViewModel)DataContext).MyInitializer(); };
}
If you find the syntax confusing you might want to read up on Anonymous methods and Subscribing to event handlers (using anonymous methods).
I'm using similar solution like Hogler only with reflection (lazy coupled solution). I dont want referencing specific type of my ViewModel (because of generality, interchangeability, etc.).
public MyControl()
{
InitializeComponent();
Loaded += MyControl_Loaded;
}
private void MyControl_Loaded(object sender, RoutedEventArgs e)
{
(DataContext.GetType().GetProperty("LoadedCommand")?.
GetValue(DataContext) as ICommand)?.
Execute(null);
}
ViewModel can (dont have to) contain desired command like property (LoadedCommand in this case). Nothing more.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With