I'm using Microsoft Expression Blend 4
I have a Browser ..,
[ XAML ] ConnectionView " Empty Code Behind "
<WebBrowser local:AttachedProperties.BrowserSource="{Binding Source}"> <i:Interaction.Triggers> <i:EventTrigger> <i:InvokeCommandAction Command="{Binding LoadedEvent}"/> </i:EventTrigger> <i:EventTrigger EventName="Navigated"> <i:InvokeCommandAction Command="{Binding NavigatedEvent}" CommandParameter="??????"/> </i:EventTrigger> </i:Interaction.Triggers> </WebBrowser>
[ C# ] AttachedProperties class
public static class AttachedProperties { public static readonly DependencyProperty BrowserSourceProperty = DependencyProperty . RegisterAttached ( "BrowserSource" , typeof ( string ) , typeof ( AttachedProperties ) , new UIPropertyMetadata ( null , BrowserSourcePropertyChanged ) ); public static string GetBrowserSource ( DependencyObject _DependencyObject ) { return ( string ) _DependencyObject . GetValue ( BrowserSourceProperty ); } public static void SetBrowserSource ( DependencyObject _DependencyObject , string Value ) { _DependencyObject . SetValue ( BrowserSourceProperty , Value ); } public static void BrowserSourcePropertyChanged ( DependencyObject _DependencyObject , DependencyPropertyChangedEventArgs _DependencyPropertyChangedEventArgs ) { WebBrowser _WebBrowser = _DependencyObject as WebBrowser; if ( _WebBrowser != null ) { string URL = _DependencyPropertyChangedEventArgs . NewValue as string; _WebBrowser . Source = URL != null ? new Uri ( URL ) : null; } } }
[ C# ] ConnectionViewModel Class
public class ConnectionViewModel : ViewModelBase { public string Source { get { return Get<string> ( "Source" ); } set { Set ( "Source" , value ); } } public void Execute_ExitCommand ( ) { Application . Current . Shutdown ( ); } public void Execute_LoadedEvent ( ) { MessageBox . Show ( "___Execute_LoadedEvent___" ); Source = ...... ; } public void Execute_NavigatedEvent ( ) { MessageBox . Show ( "___Execute_NavigatedEvent___" ); } }
[ C# ] ViewModelBase class Here
Finally :
Binding with commands works well and MessageBoxes shown
My Question :
How to pass NavigationEventArgs as Command Parameters when Navigated Event occurs ?
It's not easily supported. Here's an article with instructions on how to pass EventArgs as command parameters.
You might want to look into using MVVMLight - it supports EventArgs in command directly; your situation would look something like this:
<i:Interaction.Triggers> <i:EventTrigger EventName="Navigated"> <cmd:EventToCommand Command="{Binding NavigatedEvent}" PassEventArgsToCommand="True" /> </i:EventTrigger> </i:Interaction.Triggers>
I try to keep my dependencies to a minimum, so I implemented this myself instead of going with EventToCommand of MVVMLight. Works for me so far, but feedback is welcome.
Xaml:
<i:Interaction.Behaviors> <beh:EventToCommandBehavior Command="{Binding DropCommand}" Event="Drop" PassArguments="True" /> </i:Interaction.Behaviors>
ViewModel:
public ActionCommand<DragEventArgs> DropCommand { get; private set; } this.DropCommand = new ActionCommand<DragEventArgs>(OnDrop); private void OnDrop(DragEventArgs e) { // ... }
EventToCommandBehavior:
/// <summary> /// Behavior that will connect an UI event to a viewmodel Command, /// allowing the event arguments to be passed as the CommandParameter. /// </summary> public class EventToCommandBehavior : Behavior<FrameworkElement> { private Delegate _handler; private EventInfo _oldEvent; // Event public string Event { get { return (string)GetValue(EventProperty); } set { SetValue(EventProperty, value); } } public static readonly DependencyProperty EventProperty = DependencyProperty.Register("Event", typeof(string), typeof(EventToCommandBehavior), new PropertyMetadata(null, OnEventChanged)); // Command public ICommand Command { get { return (ICommand)GetValue(CommandProperty); } set { SetValue(CommandProperty, value); } } public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(EventToCommandBehavior), new PropertyMetadata(null)); // PassArguments (default: false) public bool PassArguments { get { return (bool)GetValue(PassArgumentsProperty); } set { SetValue(PassArgumentsProperty, value); } } public static readonly DependencyProperty PassArgumentsProperty = DependencyProperty.Register("PassArguments", typeof(bool), typeof(EventToCommandBehavior), new PropertyMetadata(false)); private static void OnEventChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var beh = (EventToCommandBehavior)d; if (beh.AssociatedObject != null) // is not yet attached at initial load beh.AttachHandler((string)e.NewValue); } protected override void OnAttached() { AttachHandler(this.Event); // initial set } /// <summary> /// Attaches the handler to the event /// </summary> private void AttachHandler(string eventName) { // detach old event if (_oldEvent != null) _oldEvent.RemoveEventHandler(this.AssociatedObject, _handler); // attach new event if (!string.IsNullOrEmpty(eventName)) { EventInfo ei = this.AssociatedObject.GetType().GetEvent(eventName); if (ei != null) { MethodInfo mi = this.GetType().GetMethod("ExecuteCommand", BindingFlags.Instance | BindingFlags.NonPublic); _handler = Delegate.CreateDelegate(ei.EventHandlerType, this, mi); ei.AddEventHandler(this.AssociatedObject, _handler); _oldEvent = ei; // store to detach in case the Event property changes } else throw new ArgumentException(string.Format("The event '{0}' was not found on type '{1}'", eventName, this.AssociatedObject.GetType().Name)); } } /// <summary> /// Executes the Command /// </summary> private void ExecuteCommand(object sender, EventArgs e) { object parameter = this.PassArguments ? e : null; if (this.Command != null) { if (this.Command.CanExecute(parameter)) this.Command.Execute(parameter); } } }
ActionCommand:
public class ActionCommand<T> : ICommand { public event EventHandler CanExecuteChanged; private Action<T> _action; public ActionCommand(Action<T> action) { _action = action; } public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { if (_action != null) { var castParameter = (T)Convert.ChangeType(parameter, typeof(T)); _action(castParameter); } } }
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