views:

279

answers:

3

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
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
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
+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
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
True, you'll have to reference System.Windows.Interactivity (45K) and Expression.Samples.Interactivity (53K) for this to work.
PL