I use behavior implemented as an attached property. It has two main advantages compared to System.Windows.Interactivity:
- it can be defined in style.
- much less xaml code in views
in your case, the view may look like this:
<UserControl ... my:AttachedCommands.LoadedCommand="{Binding ViewLoadedCommand}">
In my solution, I do not use commands, but I call methods on the viewmodel if viewmodel implements the IViewModelLifeCycle interface:
public interface IViewModelLifeCycle { void Activate(object extraData); void Deactivate(); }
All my views use this style:
<Style x:Key="ViewBaseStyle"> <Setter Property="my:ViewModelLifeCycleBehavior.ActivateOnLoad" Value="True" />
and behavior:
public static class ViewModelLifeCycleBehavior { public static readonly DependencyProperty ActivateOnLoadProperty = DependencyProperty.RegisterAttached("ActivateOnLoad", typeof (bool), typeof (ViewModelLifeCycleBehavior), new PropertyMetadata(ActivateOnLoadPropertyChanged)); public static void SetActivateOnLoad(FrameworkElement element, bool value) { element.SetValue(ActivateOnLoadProperty, value); } public static bool GetActivateOnLoad(FrameworkElement element) { return (bool)element.GetValue(ActivateOnLoadProperty); } private static void ActivateOnLoadPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { if (DesignerProperties.GetIsInDesignMode(obj)) return; var element = (FrameworkElement)obj; element.Loaded -= ElementLoaded; element.Unloaded -= ElementUnloaded; if ((bool) args.NewValue == true) { element.Loaded += ElementLoaded; element.Unloaded += ElementUnloaded; } } static void ElementLoaded(object sender, RoutedEventArgs e) { var element = (FrameworkElement) sender; var viewModel = (IViewModelLifeCycle) element.DataContext; if (viewModel == null) { DependencyPropertyChangedEventHandler dataContextChanged = null; dataContextChanged = (o, _e) => { ElementLoaded(sender, e); element.DataContextChanged -= dataContextChanged; }; element.DataContextChanged += dataContextChanged; } else if (element.ActualHeight > 0 && element.ActualWidth > 0)
Tip: Create your custom item template in Visual Studio for View and ViewModel. Its very easy and saves a lot of time. An element template can contain xaml code with trigger / behavior, pointing to your base style, your d:DataContext definition, and the viewmodel class.
source share