InvokeDataCommand - CommandParameter

Sep 4, 2009 at 7:01 PM

I am attempting to use the InvokeDataCommand Action with the CommandParameter Property, but I am getting an AG_E_PARSER_BAD_PROPERTY_VALUE.

 

The XAML looks like this:

 

<ComboBox ItemsSource="{Binding AvailableItems}" DisplayMemberPath="Name">
  <Interactivity:Interaction.Triggers>
    <Interactivity:EventTrigger EventName="SelectionChanged">
      <si:InvokeDataCommand Command="{Binding SetOtherItemsCommand}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource Self}}"/>
    </Interactivity:EventTrigger>
  </Interactivity:Interaction.Triggers>
</ComboBox>

 

 

If I were to remove the Binding within the CommandParameter, I do not receive the AG_E_PARSER_BAD_PROPERTY_VALUE, however if I bind to anything (even if it is a property on the DataContext) AG_E_PARSER_BAD_PROPERTY_VALUE error.
Does the CommandParameter not support binding?  I looked at the code and CommandParameter is a DependencyProperty.  I must be missing something.

Thanks
Oct 21, 2009 at 11:57 AM
Edited Oct 21, 2009 at 12:04 PM

The basic of this error is that CommandParameter is not Bindable as InvokeDataCommand does not implement binding feature.
You can invoke command and pass static string message but you can not bind it or I at least I could not find it and got each iteration similar error. 

I made a quick fix for this issue and will work with following code and xaml....

public ICommand SetOtherItemsCommand { get; private set; }
SetOtherItemsCommand = new DelegateCommand(ExecuteSetOtherItemsCommand, CanSetOtherItemsCommand());

private bool CanSetOtherItemsCommand()
{
  return true;
}

private void ExecuteSetOtherItemsCommand(object selectedItem)
{
// todo something usefull with you selecteItem here…
}

<ComboBox x:Name="MyComboBox" ItemsSource="{Binding AvailableItems}" DisplayMemberPath="Name">

<i:Interaction.Triggers>
 <i:EventTrigger EventName="SelectionChanged">
   <ci:InvokeDataCommand 
 	Command="{Binding MenuItemSelectedCommand}"  
CommandParameter="{Binding SelectedItem, ElementName=MyComboBox,Mode=TwoWay}"/>
  </i:EventTrigger>
 </i:Interaction.Triggers>

</ComboBox>
Replace your InvokeDataCommand implmentation with following 
 /// <summary>
	/// Invokes a command which is exposed by the data context.
	/// </summary>
	public class InvokeDataCommand : TriggerAction<FrameworkElement> 
    {

		/// <summary>Backing DP for the Command property</summary>
		public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(Binding), typeof(InvokeDataCommand), new PropertyMetadata(null, InvokeDataCommand.HandleCommandChanged));

		/// <summary>Backing DP for the CommandParameter property</summary>
        public static readonly DependencyProperty CommndParameterProperty = DependencyProperty.Register("CommandParameter", typeof(Binding), typeof(InvokeDataCommand), new PropertyMetadata(null, InvokeDataCommand.HandleCommandParameterChanged));

		private BindingListener listenerCmd = new BindingListener();
        private BindingListener listenerCmdParam = new BindingListener();
       
		/// <summary>
		/// Binding to the command which is to be invoked
		/// </summary>
		public Binding Command 
        {
			get { return (Binding)this.GetValue(InvokeDataCommand.CommandProperty); }
			set { this.SetValue(InvokeDataCommand.CommandProperty, value); }
		}

        /// <summary>
		/// Optional parameter for the command.
		/// </summary>
        public Binding CommandParameter 
        {
            get { return (Binding)this.GetValue(InvokeDataCommand.CommndParameterProperty); }
            set { this.SetValue(InvokeDataCommand.CommndParameterProperty, value); }
		}

		/// <summary>
		/// Initialization
		/// </summary>
		protected override void OnAttached() 
        {
			base.OnAttached();
			this.listenerCmd.Element = this.AssociatedObject;
            this.listenerCmdParam.Element = this.AssociatedObject;
		}

		/// <summary>
		/// Cleanup
		/// </summary>
		protected override void OnDetaching() 
        {
			base.OnDetaching();
			this.listenerCmd.Element = null;
            this.listenerCmdParam.Element = null;
		}

        /// <summary>
		/// Fire the command.
		/// </summary>
		/// <param name="parameter"></param>
		protected override void Invoke(object parameter) {

			ICommand command = this.listenerCmd.Value as ICommand;
            object param = this.listenerCmdParam.Value as object;

            if (command != null && command.CanExecute(param))
            {
                command.Execute(param);
			}
		}

		private static void HandleCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
        {
			((InvokeDataCommand)sender).OnCommandChanged(e);
		}
        private static void HandleCommandParameterChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
        {
			((InvokeDataCommand)sender).OnParametersChanged(e);
		}
		/// <summary>
		/// Notification that the command property has changed.
		/// </summary>
		/// <param name="e"></param>
		protected virtual void OnCommandChanged(DependencyPropertyChangedEventArgs e) 
        {
            this.listenerCmd.Binding = this.Command;
		}
        /// <summary>
        /// Notification that the command property parameters has changed.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnParametersChanged(DependencyPropertyChangedEventArgs e)
        {
            this.listenerCmdParam.Binding = this.CommandParameter;
        }
	}
Regards, 
Alexander