Control Events not being invoked
Good evening!
I tried several ways to listen for KeyDown events for a TextBox control, unfortunately without success.
The case is pretty simple: I have a UserControl containing a Grid which contains a TextBox. I want to listen to the KeyDown event. Entering text in the TextBox by typing works as expected, but the KeyDown event is never called - independently by the way of registering the event (by XAML or code behind).
Am I missing something?
Thank you in advance :)
I tried several ways to listen for KeyDown events for a TextBox control, unfortunately without success.
The case is pretty simple: I have a UserControl containing a Grid which contains a TextBox. I want to listen to the KeyDown event. Entering text in the TextBox by typing works as expected, but the KeyDown event is never called - independently by the way of registering the event (by XAML or code behind).
Am I missing something?
Thank you in advance :)
Update: Control Events not being invoked
Update: It seems that no events are registered at all. I additionally created a Button today and added a Click-event handler (first by XAML, then in code behind only) and it does not work at all.
XAML
C#
It's pretty simple. The PanelVisible property is working, the Binding works too.
XAML
Code: Select all
<UserControl x:Class="SL.RuadhSagas.UI.Misc.DevConsoleUI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
</UserControl.Resources>
<Grid VerticalAlignment="Top"
MinWidth="720"
MinHeight="256"
HorizontalAlignment="Center"
Visibility="{Binding Path=PanelVisible, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibility}}"
Background="#CC000000">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="45" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0"
Orientation="Vertical"
Margin="5">
<TextBlock Text="Development Console v1"
Foreground="White" />
</StackPanel>
<Grid Grid.Row="1"
Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Name="CommandInput"
Foreground="White" />
<Button Grid.Column="1"
Name="CommandExecute"
Content="Run" />
</Grid>
</Grid>
</UserControl>
Code: Select all
#if UNITY_5_3_OR_NEWER
#define NOESIS
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
using Noesis;
using UnityEngine;
#else
using System;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
#endif
namespace SL.RuadhSagas.UI.Misc
{
public partial class DevConsoleUI : UserControl, INotifyPropertyChanged
{
private bool _panelVisible;
private TextBox cmdInput;
private Button cmdExecute;
public bool PanelVisible
{
get => _panelVisible;
set
{
if (value == _panelVisible)
return;
_panelVisible = value;
OnPropertyChanged();
}
}
public DevConsoleUI()
{
InitializeComponent();
DataContext = this;
cmdInput = FindName("CommandInput") as TextBox;
cmdExecute = FindName("CommandExecute") as Button;
}
private void CommandInput_OnKeyDown(object sender, KeyEventArgs e)
{
var cIn = sender as TextBox;
if (e.Key != Key.Enter && e.Key != Key.Return)
return;
var cmdStr = cIn.Text;
cIn.Clear();
Debug.Log($"Command entered: {cmdStr}");
e.Handled = true;
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
Debug.Log("Test123");
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
#if NOESIS
private void InitializeComponent()
{
NoesisUnity.LoadComponent(this);
}
#endif
}
}
-
sfernandez
Site Admin
- Posts: 3005
- Joined:
Re: Control Events not being invoked
Hi, you are not hooking to those events anywhere in the code. You should do something like this:
Also note that TextBox handles KeyDown events (for some keys), so you may want to hook to the PreviewKeyDown in case you want to capture the keys before the TextBox does it.
Code: Select all
public DevConsoleUI()
{
InitializeComponent();
DataContext = this;
cmdInput = FindName("CommandInput") as TextBox;
cmdInput.PreviewKeyDown += CommandInput_OnKeyDown;
cmdExecute = FindName("CommandExecute") as Button;
cmdExecute.Click += ButtonBase_OnClick;
}
Re: Control Events not being invoked
Hi there and thank you for you answer!
This is really weird. I previously had the events registered the exact same way you posted, but it didn't worked at all - while other views in the same scene worked perfectly fine! Now - after several restarts of the engine - it works as intended. In the code I posted above the event registration is probably missing because I decided to create this topic after several attempts to get it to work, so I'm sorry for the confusion at this point - the code for registering events were definitely there, I just forgot to place them back in the code before posting it here.
Anyways it seems that sometimes events are not getting registered. I'm currently using Unity 2021.2.5f1 and working with Noesis for around six month now so actually registering events shouldn't be a topic anymore :D
But for now: Thanks again for your support, as always!
This is really weird. I previously had the events registered the exact same way you posted, but it didn't worked at all - while other views in the same scene worked perfectly fine! Now - after several restarts of the engine - it works as intended. In the code I posted above the event registration is probably missing because I decided to create this topic after several attempts to get it to work, so I'm sorry for the confusion at this point - the code for registering events were definitely there, I just forgot to place them back in the code before posting it here.
Anyways it seems that sometimes events are not getting registered. I'm currently using Unity 2021.2.5f1 and working with Noesis for around six month now so actually registering events shouldn't be a topic anymore :D
But for now: Thanks again for your support, as always!
-
sfernandez
Site Admin
- Posts: 3005
- Joined:
Re: Control Events not being invoked
Do you recall if that happened when hot-reloading a xaml while you had your game playing?Anyways it seems that sometimes events are not getting registered.
Re: Control Events not being invoked
No, only at initialization time. Restarting the engine solved the problem to it's maybe not an issue with Noesis but with Unity itself. I'll let you know if I find a way to reproduce the issue :)
-
sfernandez
Site Admin
- Posts: 3005
- Joined:
Re: Control Events not being invoked
Thanks, it would help if you find a way to reproduce it because I don't think it could be a Unity problem.
Re: Control Events not being invoked
Hey there again!
Coming back to the initial question: Is it possible to use the event attributes in XAML to register events at all?
I'm working with Unity and the only way to get events to work is to manually register them inside the backend code.
Here's a simple, not working example:
Is there no way to register events by XAML attributes without manually registering them using FindName("elementName") and the respective event registration?
Edit: Almost forget ... the actual issue is, that Noesis throws an error complaining that there is no definition for "ClickHandler". Even though the handler is a public method.
Kind regards
Rico
Coming back to the initial question: Is it possible to use the event attributes in XAML to register events at all?
I'm working with Unity and the only way to get events to work is to manually register them inside the backend code.
Here's a simple, not working example:
Code: Select all
<UserControl x:Class="SL.RuadhSagas.UI.Misc.PartyInventory"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModel="clr-namespace:Ruadh_Sagas.Assets.Code.XAML.ViewModel"
xmlns:components="clr-namespace:SL.RuadhSagas.UI.Components"
mc:Ignorable="d">
<Viewbox>
<Button Content="Click me!" Click="ClickHandler" />
</Viewbox>
</UserControl>
Code: Select all
#if UNITY_5_3_OR_NEWER
#define NOESIS
using System;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using Noesis;
#else
using System;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
#endif
namespace SL.RuadhSagas.UI.Misc
{
public partial class PartyInventory : UserControl
{
public PartyInventory()
{
InitializeComponent();
}
private void ClickHandler(object sender, RoutedEventArgs e)
{
UnityEngine.Debug.Log("Clicked!");
}
#if NOESIS
private void InitializeComponent()
{
NoesisUnity.LoadComponent(this);
}
#endif
}
}
Edit: Almost forget ... the actual issue is, that Noesis throws an error complaining that there is no definition for "ClickHandler". Even though the handler is a public method.
Kind regards
Rico
Re: Control Events not being invoked
Solved this!
I missed an important override as described in https://www.noesisengine.com/docs/Gui.C ... bscription
So adding the following method override to the code behind class fixes the issue:
I'm sorry for the inconvenience.
Kind regards
Rico
I missed an important override as described in https://www.noesisengine.com/docs/Gui.C ... bscription
So adding the following method override to the code behind class fixes the issue:
Code: Select all
protected override bool ConnectEvent(object source, string eventName, string handlerName)
{
if (eventName == "Click" && handlerName == nameof(ClickHandler))
{
((Button)source).Click+= ClickHandler;
return true;
}
return false;
}
Kind regards
Rico
Re: Control Events not being invoked
Yes, that's the solution. We have plans to auto-generate this (#1790).
A much better alternative is avoiding events in XAML and just use MVVM. Just have a look at our Buttons sample in Unity.
A much better alternative is avoiding events in XAML and just use MVVM. Just have a look at our Buttons sample in Unity.
Who is online
Users browsing this forum: Bing [Bot], Google [Bot] and 2 guests