How do you implement a Silverlight 4 command to execute when the user control loads instead of being mapped to an explicit button click?
A:
Are you looking for the FrameworkElement.Loaded
event?
According to MSDN, this event occurs "when a FrameworkElement
has been constructed and added to the object tree."
So, you could use it to do something like this:
public MyCustomUserControl()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MyCustomUserControl_Loaded);
}
private void MyCustomUserControl_Loaded(object sender, RoutedEventArgs e)
{
// Do whatever you want here; it'll get executed when the control is loaded
}
Note that you can also declaratively specify the event handler for the Loaded
event in XAML:
<UserControl Loaded="MyCustomUserControl_Loaded" (...)
This has the same effect as the first example; it's really a matter of preference.
Hope this helps!
Donut
2010-04-22 20:47:50
This would work but you would be breaking the MVVM approach to do so since this code behind would need to know specifically what is to be done on loading. The ICommand interface is designed to abstract this sort of thing.
AnthonyWJones
2010-04-22 21:44:45
A:
Create a DependencyProperty
of type ICommand
:-
#region public ICommand LoadedCommand
public ICommand LoadedCommand
{
get { return GetValue(LoadedCommandProperty) as ICommand; }
set { SetValue(LoadedCommandProperty, value); }
}
public static readonly DependencyProperty LoadedCommandProperty =
DependencyProperty.Register(
"LoadedCommand",
typeof(ICommand),
typeof(MainPage),
new PropertyMetadata(null));
#endregion public ICommand LoadedCommand
Also add a something to act as the command parameter:-
#region public object LoadedCommandParameter
public object LoadedCommandParameter
{
get { return GetValue(LoadedCommandParameterProperty) as object; }
set { SetValue(LoadedCommandParameterProperty, value); }
}
public static readonly DependencyProperty LoadedCommandParameterProperty =
DependencyProperty.Register(
"LoadedCommandParameter",
typeof(object),
typeof(MainPage),
new PropertyMetadata(null));
#endregion public object LoadedCommandParameter
Now set up its execution like this:-
public UserControl1()
{
InitializeComponent();
Loaded += UserControl1_Loaded;
}
void UserControl1_Loaded(object sender, RoutedEventArgs e)
{
if (LoadedCommand != null && LoadedCommand.CanExecute(LoadedCommandParameter))
{
LoadedCommand.Execute(LoadedCommandParameter);
}
}
Now if your ViewModel (has a command called StartStuff
) then:-
<UserControl1 LoadedCommand="{Binding StartStuff}" .... >
AnthonyWJones
2010-04-22 21:42:25
+1
A:
Or simply add a trigger in xaml for your UserControl:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<si:InvokeDataCommand Command="{Binding MyCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
PL
2010-04-22 21:59:26
That works nicely but it isn't as simple as that, you need to add the appropriate references which in turn increases the application download size. If there are various other uses for these references fine but if not then a coded solution avoids the need for additional references for this requirement.
AnthonyWJones
2010-04-23 06:43:00
True, you'll have to reference System.Windows.Interactivity (45K) and Expression.Samples.Interactivity (53K) for this to work.
PL
2010-04-23 14:32:11