NoesisGUI

Events in NoesisGUI

NoesisGUI is an event driven framework where all controls expose a range of events that you may subscribe to. You can subscribe to these events, which means that your application will be notified when they occur and you may react to that.

There are many types of events, but some of the most commonly used are there to respond to the user's interaction. On most controls you will find events like KeyDown, KeyUp, MouseDown, MouseUp, TouchDown, TouchUp. For example, in the events section of the UIElement documentation you can find a list of all the events exposed by that class. The same for the rest of classes.

Note

Find more information about events in the Events Overview document.

Two different ways can be used to subscribe to events in NoesisGUI: with and without code-behind.

Direct subscription

The easiest way to subscribe to an event is by directly adding a callback to it by using a delegate. The object is reached using FindName, so you need to use the x:Name keyword to set the name of the desired instance. For example:

<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Button x:Name="button" Width="100" VerticalAlignment="Center" Content="Click me"/>

</Grid>
C++
Ptr<Grid> root = Noesis::GUI::LoadXaml<Grid>("Grid.xaml");
Button* button = root->FindName<Button>("button");
button->Click() += [](BaseComponent* sender, const RoutedEventArgs& args)
{
    printf("Button was clicked");
};
C#
Grid root = (Grid)Noesis.GUI.LoadXaml("Grid.xaml");
Button button = (Button)root.FindName("button");
button.Click += (object sender, RoutedEventArgs args) =>
{
    System.Console.WriteLine("Button was clicked");
};

Code-behind subscription

The alternative to direct subscription is using a code-behind class and connecting events in the XAML by using method names. These method names need to be implemented in the code-behind class using the correct event signature. For example:

<Grid x:Class="MyGrid"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Button Width="100" VerticalAlignment="Center" Content="Click me" Click="OnButtonClick"/>
</Grid>

Note

Read the Extending Noesis tutorial to know more about implementing code-behind classes

FrameworkElement exposes the virtual function ConnectEvent that is invoked for each hooked event when the XAML is loaded. You need to override that function accordingly. In C++ the macro NS_CONNECT_EVENT is provider as a helper to easily implement ConnectEvent.

C++
class MyGrid: public Grid
{
public:
    MyGrid()
    {
        InitializeComponent();
    }

private:
    void InitializeComponent()
    {
        Noesis::GUI::LoadComponent(this, "Grid.xaml");
    }

    bool ConnectEvent(BaseComponent* source, const char* event, const char* handler) override
    {
        NS_CONNECT_EVENT(Button, Click, OnButtonClick);
        return false;
    }

    void OnButtonClick(BaseComponent* sender, const RoutedEventArgs& args)
    {
        printf("Button was clicked");
    }

    NS_IMPLEMENT_INLINE_REFLECTION(MyGrid, Grid)
    {
        NsMeta<TypeId>("MyGrid");
    }
};
C#
public class MyGrid: Grid
{
    public MyGrid()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        Noesis.GUI.LoadComponent(this, "Grid.xaml");
    }

    protected override void Connect(object source, string eventName, string handlerName)
    {
        if (eventName == "Click" && handlerName == "OnButtonClick")
        {
            ((Button)source).Click += this.OnButtonClick;
        }
    }

    private void OnButtonClick(object sender, RoutedEventArgs args)
    {
        System.Console.WriteLine("Button was clicked");
    }
}

Note that sometimes using FindName is not a valid option and using code-behind member functions is the only way to connect to events. For example when using a DataTemplate the named elements in the visual tree cannot be accessed using FindName because the data template is replicated for each item.

<Grid x:Class="MyGrid"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid.Resources>
    <DataTemplate x:Key="BookItemTemplate">
      <StackPanel Orientation="Horizontal">
        <Button Content="+" Click="OnButtonClick" />
        <TextBlock Text="{Binding Title}"/>
      </StackPanel>
    </DataTemplate>
  </Grid.Resources>
  <ListBox ItemsSource="{Binding Books}" ItemTemplate="{StaticResource BookItemTemplate}"/>
</Grid>
© 2017 Noesis Technologies