Using EventTriggers gives error
Hi,
we are in need to get MouseEnter and MouseExit from buttons or their images with id parameter. These buttons live in an ItemsControl.
I have tried using System.Windows.Interactivity namespace to use Triggers, but with little luck. If I use Trigger it gives me this error:
NoesisException: Resource Assets/GloryAssets/Cok_Xaml/Editors/UserControls/ArenaEditorWindow.xaml not found
Noesis.Error.Check () (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisError.cs:26)
Noesis.UIRenderer.Noesis_CreateRenderer (IntPtr root) (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisUIRendererImports.cs:90)
Noesis.UIRenderer..ctor (Noesis.FrameworkElement content, Vector2 offscreenSize, UnityEngine.GameObject target) (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisUIRenderer.cs:117)
NoesisGUIPanel.LoadXaml () (at Assets/Plugins/NoesisGUI/Scripts/NoesisGUIPanel.cs:529)
NoesisGUIPanel.OnEnable () (at Assets/Plugins/NoesisGUI/Scripts/NoesisGUIPanel.cs:400)
Namespace:
Sample button:
we are in need to get MouseEnter and MouseExit from buttons or their images with id parameter. These buttons live in an ItemsControl.
I have tried using System.Windows.Interactivity namespace to use Triggers, but with little luck. If I use Trigger it gives me this error:
NoesisException: Resource Assets/GloryAssets/Cok_Xaml/Editors/UserControls/ArenaEditorWindow.xaml not found
Noesis.Error.Check () (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisError.cs:26)
Noesis.UIRenderer.Noesis_CreateRenderer (IntPtr root) (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisUIRendererImports.cs:90)
Noesis.UIRenderer..ctor (Noesis.FrameworkElement content, Vector2 offscreenSize, UnityEngine.GameObject target) (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisUIRenderer.cs:117)
NoesisGUIPanel.LoadXaml () (at Assets/Plugins/NoesisGUI/Scripts/NoesisGUIPanel.cs:529)
NoesisGUIPanel.OnEnable () (at Assets/Plugins/NoesisGUI/Scripts/NoesisGUIPanel.cs:400)
Namespace:
Code: Select all
<UserControl x:Class="Assets.GloryAssets.Scripts.GUI.UserControls.ArenaEditorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Assets.GloryAssets.Scripts.GUI.UserControls"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d"
d:DesignHeight="1080" d:DesignWidth="1920"
x:Name="root">
Code: Select all
<Button Content="Button" Width="300" Height="50">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding PropItemMouseEnterCommand}"
CommandParameter="1" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Using EventTriggers gives error
Hi,
Interactivity namespace is defined by a Blend SDK extension assembly and we don't implement it.
Anyway we implement the standard WPF EventTriggers that can be used in FrameworkElement.Triggers and inside ControlTemplate.Triggers collections.
Have you tried that?
The error message seems to point to a syntax error during xaml parsing, so xaml resource is not correctly generated. When a xaml is processed we dump warning and error messages to Unity Console, and we also show in NoesisGUIPanel if the attached xaml has errors, as explained in our tutorial: http://www.noesisengine.com/docs/Gui.Co ... -noesisgui
Regards.
Interactivity namespace is defined by a Blend SDK extension assembly and we don't implement it.
Anyway we implement the standard WPF EventTriggers that can be used in FrameworkElement.Triggers and inside ControlTemplate.Triggers collections.
Code: Select all
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource onLoadedAnim}"/>
</EventTrigger>
</Grid.Triggers>
Code: Select all
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard Storyboard="{StaticResource onMouseEnterAnim}"/>
</EventTrigger>
</ControlTemplate.Triggers>
The error message seems to point to a syntax error during xaml parsing, so xaml resource is not correctly generated. When a xaml is processed we dump warning and error messages to Unity Console, and we also show in NoesisGUIPanel if the attached xaml has errors, as explained in our tutorial: http://www.noesisengine.com/docs/Gui.Co ... -noesisgui
Regards.
Re: Using EventTriggers gives error
Hey,
is it possible to use commands with the WPF EventTriggers?
is it possible to use commands with the WPF EventTriggers?
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Using EventTriggers gives error
No, it is not possible to invoke a Command directly from the EventTrigger.
But it can be done using animation and a custom class that stores and invokes the command, something like this:
But it can be done using animation and a custom class that stores and invokes the command, something like this:
Code: Select all
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Rectangle x:Name="rect" Width="200" Height="100" Fill="Red">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Storyboard.TargetName="enterCommandInvoker"
Storyboard.TargetProperty="Invoke">
<DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.01" Value="False"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
<InvokeCommand x:Name="enterCommandInvoker" Command="{Binding EnterCommand}"
CommandParameter="{Binding ElementName=rect}"/>
</Grid>
Code: Select all
public class InvokeCommand: FrameworkElement
{
public static DependencyProperty CommandProperty = DependencyProperty.Register(
"Command", typeof(ICommand), typeof(InvokeCommand), new PropertyMetadata(null));
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static DependencyProperty CommandParameterProperty = DependencyProperty.Register(
"CommandParameter", typeof(object), typeof(InvokeCommand), new PropertyMetadata(null));
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public static DependencyProperty InvokeProperty = DependencyProperty.Register(
"Invoke", typeof(bool), typeof(InvokeCommand),
new PropertyMetadata(false, OnInvokeChanged));
public bool Invoke
{
get { return (bool)GetValue(InvokeProperty); }
set { SetValue(InvokeProperty, value); }
}
private static void OnInvokeChanged(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
bool invoke = (bool)e.NewValue;
if (invoke)
{
InvokeCommand invoker = (InvokeCommand)sender;
invoker.Command.Execute(invoker.CommandParameter);
}
}
}
Re: Using EventTriggers gives error
Hey, thanks for the reply. I can successfully use the rectangle and trigger the MouseEnter event. However, in Blend I can't use this part:
"The type InvokeCommand was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built."
I have included InvokeCommand.cs in the Blend project and built the project but with no help.
Code: Select all
<InvokeCommand x:Name="enterCommandInvoker" Command="{Binding EnterCommand}"
CommandParameter="{Binding ElementName=rect}"/>
I have included InvokeCommand.cs in the Blend project and built the project but with no help.
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Using EventTriggers gives error
I think you would need to use a xaml namespace.
In which namespace is InvokeCommand class defined in Blend?
For example, if you have the class defined like this:
You have to add the following in your xaml:
In which namespace is InvokeCommand class defined in Blend?
For example, if you have the class defined like this:
Code: Select all
namespace Esses
{
public class InvokeCommand: FrameworkElement { ... }
}
Code: Select all
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Esses">
...
<local:InvokeCommand .../>
...
</Grid>
Re: Using EventTriggers gives error
Hey, thanks for the reply. Now it's defined in Blend. For some reason the command doesn't fire though.
I put the InvokeCommand.cs in Assets.GloryAssets.Scripts.GUI.NoesisCommands namespace:
ArenaEditorWindow.xaml.cs:
If I remove the line
on mouse enter I get the following error:
NoesisException: The target name 'enterCommandInvoker' cannot be found in the xaml namescope
Noesis.Error.Check () (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisError.cs:26)
...which indicates that the mouse enter works, but for some reason the command doesn't fire at all.
I put the InvokeCommand.cs in Assets.GloryAssets.Scripts.GUI.NoesisCommands namespace:
Code: Select all
xmlns:commandou="clr-namespace:Assets.GloryAssets.Scripts.GUI.NoesisCommands"
Code: Select all
namespace Assets.GloryAssets.Scripts.GUI.NoesisCommands
{
public class InvokeCommand : FrameworkElement
{
public static DependencyProperty CommandProperty = DependencyProperty.Register(
"Command", typeof(ICommand), typeof(InvokeCommand), new PropertyMetadata(null));
public ICommand Command
ArenaEditorWindow.xaml.cs:
Code: Select all
public DelegateCommand EnterCommand { get; private set; }
Code: Select all
public ArenaEditorWindow()
{
[..]
EnterCommand = new DelegateCommand(Enter);
this.Initialized += OnInitialized;
#if UNITY
InitializeComponent();
[..]
If I remove the line
Code: Select all
<commandou:InvokeCommand x:Name="enterCommandInvoker" Command="{Binding EnterCommand}"
CommandParameter="{Binding ElementName=rect}"/>
NoesisException: The target name 'enterCommandInvoker' cannot be found in the xaml namescope
Noesis.Error.Check () (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisError.cs:26)
...which indicates that the mouse enter works, but for some reason the command doesn't fire at all.
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Using EventTriggers gives error
I made a simple example to show you how can be done, it is working fine for me.
InvokeCommandTestBehavior.cs
InvokeCommandTest.xaml
I added a NoesisGUIPanel component to the Main Camera object, then drag and drop InvokeCommandTest.xaml to its Xaml property, and finally added too InvokeCommandTestBehavior script to Main Camera.
After clicking play, a message is written to the Console every time mouse enters the red rectangle.
Please let me know if you don't understand anything from the example, or if you can't make it work.
InvokeCommandTestBehavior.cs
Code: Select all
using UnityEngine;
using System.Windows.Input;
using Noesis;
namespace Assets.InvokeCommandTest
{
public class InvokeCommand : FrameworkElement
{
public static DependencyProperty CommandProperty = DependencyProperty.Register(
"Command", typeof(ICommand), typeof(InvokeCommand), new PropertyMetadata(null));
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static DependencyProperty CommandParameterProperty = DependencyProperty.Register(
"CommandParameter", typeof(object), typeof(InvokeCommand), new PropertyMetadata(null));
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public static DependencyProperty InvokeProperty = DependencyProperty.Register(
"Invoke", typeof(bool), typeof(InvokeCommand),
new PropertyMetadata(false, OnInvokeChanged));
public bool Invoke
{
get { return (bool)GetValue(InvokeProperty); }
set { SetValue(InvokeProperty, value); }
}
private static void OnInvokeChanged(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
bool invoke = (bool)e.NewValue;
if (invoke)
{
InvokeCommand invoker = (InvokeCommand)sender;
invoker.Command.Execute(invoker.CommandParameter);
}
}
}
public class Context
{
public ICommand EnterCommand { get; private set; }
public Context()
{
EnterCommand = new Noesis.Samples.DelegateCommand(OnEnter);
}
private void OnEnter(object param)
{
FrameworkElement element = (FrameworkElement)param;
Debug.Log("OnMouseEnter: " + (element != null ? element.Name : "?"));
}
}
}
public class InvokeCommandTestBehavior : MonoBehaviour
{
void Start()
{
var gui = GetComponent<NoesisGUIPanel>();
var content = gui.GetContent();
content.DataContext = new Assets.InvokeCommandTest.Context();
}
}
Code: Select all
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Assets.InvokeCommandTest">
<Rectangle x:Name="rect" Width="200" Height="100" Fill="Red">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Storyboard.TargetName="enterCommandInvoker"
Storyboard.TargetProperty="Invoke">
<DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.01" Value="False"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
<local:InvokeCommand x:Name="enterCommandInvoker"
Command="{Binding EnterCommand}"
CommandParameter="{Binding ElementName=rect}"/>
</Grid>
After clicking play, a message is written to the Console every time mouse enters the red rectangle.
Please let me know if you don't understand anything from the example, or if you can't make it work.
Re: Using EventTriggers gives error
Hey, it worked for a while. I had placed the files not in Assets/InvokeCommandTest folder and wondered if it would work after moving them to that folder. For some reason it started working after moving. Then I tried to confirm this by moving them away from that folder, and it still worked (?). But now it stopped working. I don't even get the error anymore when hovering, but the red square is drawn correctly.
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Using EventTriggers gives error
The folder where you place the files shouldn't matter, because the namespace could be whatever you want.
What you have to make sure is that the xaml is correctly processed (without errors) after the InvokeCommand class is compiled and available in the assembly.
Try to rebuild xaml resources to see if there is some synchronization problems between data and code. You can do that in Tools > NoesisGUI > Settings... panel from Unity's top menu, by pressing the 'Rebuild' button.
What you have to make sure is that the xaml is correctly processed (without errors) after the InvokeCommand class is compiled and available in the assembly.
Try to rebuild xaml resources to see if there is some synchronization problems between data and code. You can do that in Tools > NoesisGUI > Settings... panel from Unity's top menu, by pressing the 'Rebuild' button.
Who is online
Users browsing this forum: Google [Bot] and 1 guest