locked
The specified value cannot be assigned to the collection. the following type was expected: "TriggerAction". RRS feed

  • Question

  • Hello,

    Quite simple, I cannot see my design in Blend3 anymore, I don't know what changed much.
    Here is one of my View:

    <Window x:Class="LacT.Animal.Windows.BreedingWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:LacT.Animal.Windows"
        xmlns:i="clr-namespace:Microsoft.Expression.Interactivity;assembly=Microsoft.Expression.Interactivity"
    	  xmlns:lcw="clr-namespace:LacT.Core.Windows;assembly=LacT.Core.Windows"
            >
    
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="0.509*"/>
          <ColumnDefinition Width="0.491*"/>
        </Grid.ColumnDefinitions>
    
        <!--Cette petite ligne me force à créer une classe à chaque fois-->
        <!--TODO MartinLamontagne trouver un moyen de diminuer le nombre de classe créer pour ces fenêtre-->
        <this:BreedingView DataContext="{Binding}" Margin="0,0,0,1.83" Grid.ColumnSpan="2"/>
    
        <Rectangle Stroke="Black" StrokeThickness="0" Margin="0,2.17,0,-3.158" Grid.ColumnSpan="2" Grid.Row="1">
          <Rectangle.Fill>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
              <GradientStop Color="#FF1A2134" Offset="0"/>
              <GradientStop Color="White" Offset="1"/>
              <GradientStop Color="#FF7183B6" Offset="0.043"/>
              <GradientStop Color="#FFECEDF2" Offset="0.957"/>
            </LinearGradientBrush>
          </Rectangle.Fill>
        </Rectangle>
    
        <Button x:Name="OkButton" HorizontalAlignment="Right" Margin="0,8,17,0" Width="114.903" Content="{Binding OkButtonCommand.Name}" Grid.Row="1" VerticalAlignment="Top" Height="25" 
                Click="OkButton_Click">
          <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click" >
              <lcw:CommandAction Command="{Binding OkButtonCommand}" SyncOwnerIsEnabled="True"/>
            </i:EventTrigger>
          </i:Interaction.Triggers>
        </Button>
        <Button x:Name="CancelButton" Margin="17,8,0,0" Content="Annuler" HorizontalAlignment="Left" Width="114.903" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="25" 
                Click="CancelButton_Click"/>
      </Grid>         
    </Window>

    With this error: The specified value cannot be assigned to the collection. the following type was expected: "TriggerAction".

    on this line: <this:CommandAction Command="{Binding OkButtonCommand}" SyncOwnerIsEnabled="True"/>

    Here is my CommandAction Class, which is the blend expression one with french comment:

    using System;
    using System.Windows;
    using Microsoft.Expression.Interactivity;
    using System.ComponentModel;
    using System.Windows.Input;
    
    namespace LacT.Core.Windows
    {
      /// <summary>
      /// Martin Lamontagne (Inspiré à 100% du Expression Blend team blog)
      /// 
      /// Le CommandAction permet de lié des FrameworkElements
      /// à une Command. (routed)
      /// 
      /// Par exemple, il rend possible de spécifé (directement dans le Xaml)
      /// Que sur le right-click d'un cercle d'exécuté une Command qui afficherais
      /// un messagebox
      /// 
      /// Les propriétés CommandParameter et CommandTarget sont fournies
      /// pour être consistent avec le Wpf Command pattern.
      /// 
      /// L'action sur la propriétés IsEnabled mettra à jour selon la valeur
      /// CanExecute de la valeur!!!(Eh oui! Toute seule comme une grande.)
      /// 
      /// De plus, l'addition de la propriétée SyncOwnerIsEnabled permet à 
      /// l'utilisateur de spécifié que le Owner Element doit être à 
      /// enabled/disabled quand l'action est à enabled/disabled
      /// 
      /// </summary>    
      public class CommandAction : TargetedTriggerAction<FrameworkElement>, ICommandSource
      {
        #region DepedencyProperties
    
        #region Command DepedencyProperty
        /// <summary>
        /// La Command à déclencher que l'évènement
        /// EventTrigger se produit, ainsi
        /// déclenchant cette commande CommandAction
        /// </summary>
        [Category("Command Properties")]
        public ICommand Command
        {
          get { return (ICommand)GetValue(CommandProperty); }
          set { SetValue(CommandProperty, value); }
        }
    
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register(
                "Command", typeof(ICommand), typeof(CommandAction),
                    new PropertyMetadata(
                        (ICommand)null, OnCommandChanged));
    
        private static void OnCommandChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
          var action = (CommandAction)d;
          action.OnCommandChanged((ICommand)e.OldValue, (ICommand)e.NewValue);
        }
    
        #region Command implementation
    
        /// <summary>
        /// This is a strong reference to the Command.CanExecuteChanged event handler. 
        /// The commanding system uses a weak reference and if we don't enforce a 
        /// strong reference then the event handler will be gc'ed.
        /// En gros, il faut le déclarer en stron reference sinon is se fait bouffé
        /// par le Garbage Collector et on perd le handler.
        /// </summary>
        private EventHandler CanExecuteChangedHandler;
    
    
    
        private void OnCommandChanged(ICommand oldCommand, ICommand newCommand)
        {
          if (oldCommand != null)
            UnhookCommand(oldCommand);
          if (newCommand != null)
            HookCommand(newCommand);
        }
    
        private void UnhookCommand(ICommand command)
        {
          command.CanExecuteChanged -= CanExecuteChangedHandler;
          UpdateCanExecute();
        }
    
        private void HookCommand(ICommand command)
        {
          // Save a strong reference to the Command.CanExecuteChanged event handler. 
          // The commanding system uses a weak reference and if we don't save a strong 
          // reference then the event handler will be gc'ed.
          /// En gros, il faut le déclarer en strong reference sinon ils se fait bouffé
          /// par le Garbage Collector et on perd le handler.
          CanExecuteChangedHandler = new EventHandler(OnCanExecuteChanged);
          command.CanExecuteChanged += CanExecuteChangedHandler;
          UpdateCanExecute();
        }
    
        private void OnCanExecuteChanged(object sender, EventArgs e)
        {
          UpdateCanExecute();
        }
    
        private void UpdateCanExecute()
        {
          if (Command != null)
          {
            RoutedCommand command = Command as RoutedCommand;
            if (command != null)
              IsEnabled = command.CanExecute(CommandParameter, CommandTarget);
            else
              IsEnabled = Command.CanExecute(CommandParameter);
            if (Target != null && SyncOwnerIsEnabled)
              Target.IsEnabled = IsEnabled;
          }
        }
    
        #endregion
    
    
        #endregion
    
        #region CommandParameter DP
        /// <summary>
        /// For consistency with the Wpf Command pattern
        /// </summary>
        [Category("Command Properties")]
        public object CommandParameter
        {
          get { return (object)GetValue(CommandParameterProperty); }
          set { SetValue(CommandParameterProperty, value); }
        }
    
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register(
                "CommandParameter", typeof(object), typeof(CommandAction),
                    new PropertyMetadata());
        #endregion
    
        #region CommandTarget DP
        /// <summary>
        /// For consistency with the Wpf Command pattern
        /// </summary>
        [Category("Command Properties")]
        public IInputElement CommandTarget
        {
          get { return (IInputElement)GetValue(CommandTargetProperty); }
          set { SetValue(CommandTargetProperty, value); }
        }
    
        public static readonly DependencyProperty CommandTargetProperty =
            DependencyProperty.Register(
                "CommandTarget", typeof(IInputElement), typeof(CommandAction),
                    new PropertyMetadata());
        #endregion
    
        #region SyncOwnerIsEnabled DP
        /// <summary>
        /// Permet à l'utilisateur de spécifié si l'owner element
        /// doit être enabled/disabled quand l'action est enabled/disabled.
        /// </summary>
        [Category("Command Properties")]
        public bool SyncOwnerIsEnabled
        {
          get { return (bool)GetValue(SyncOwnerIsEnabledProperty); }
          set { SetValue(SyncOwnerIsEnabledProperty, value); }
        }
    
        /// <summary>
        /// Quand SyncOwnerIsEnabled est True alors changé
        /// CommandAction.IsEnabled va automatiquement mettre à jour
        /// la propriété IsEnabled du owner (Target).
        /// </summary>
        public static readonly DependencyProperty SyncOwnerIsEnabledProperty =
            DependencyProperty.Register(
                "SyncOwnerIsEnabled", typeof(bool), typeof(CommandAction),
                    new PropertyMetadata());
        #endregion
    
        #endregion
    
        #region overrides
        /// <summary>
        /// Invoke est appelé quand le EventTrigger associé au
        /// TargetedTriggerAction se déclenche. De sorte qu'on
        /// peut obtenir le ICommand au quel il est lié et simplement
        /// l'exécuter.
        /// </summary>
        protected override void Invoke(object o)
        {
          if (Command != null)
          {
            var command = Command as RoutedCommand;
            if (command != null)
              command.Execute(CommandParameter, CommandTarget);
            else
              Command.Execute(CommandParameter);
          }
        }
        #endregion
      }
    }
    
    
    So why do I have this error and the demo from the team doesn't?

    Saddly I cannot show my whole project...

    Thank you for your time.

    Martin
    Wednesday, October 21, 2009 2:29 PM

All replies

  • It's probably due to the namespace declaration:

     xmlns:lcw="clr-namespace:LacT.Core.Windows;assembly=LacT.Core.Windows"

    If your CommandAction is defined in the same project as the Window, try switching it to:

     xmlns:lcw="clr-namespace:LacT.Core.Windows"

    If not, try rebuilding your LacT.Core.Windows assembly, as well as verifying that the project's reference is setup correctly.  It may be out of date, which could be preventing the designer from working correctly.

    Reed Copsey, Jr. - http://reedcopsey.com
    Wednesday, October 21, 2009 2:48 PM
  • No it's not in the same project, it's well declared. It compile and work fine, I just cannot see the design anymore in Blend. Even if I moved the CommandAction class into the same project, it didn't work.

    All my assemblies compile at the same time and the reference are hook up right I'm pretty sure. Is there some way to verify if it's out of date, maybe I misunderstood what you told me.
    • Edited by MartinLamontagne Friday, October 23, 2009 8:25 PM added clarification
    Friday, October 23, 2009 8:24 PM