美文网首页
教程4:NoesisGUI中的事件

教程4:NoesisGUI中的事件

作者: YottaYuan | 来源:发表于2020-03-13 10:34 被阅读0次

NoesisGUI中的事件

github-教程数据

NoesisGUI是一个事件驱动的框架,其中所有控件都公开了您可以订阅的一系列事件。您可以订阅这些事件,这意味着它们发生时将通知您的应用程序,您可以对此做出反应。

事件的类型很多,但是其中一些最常用的事件是用来响应用户的交互的。在大多数控件上,您会发现诸如KeyDownKeyUpMouseDownMouseUpTouchDownTouchUp之类的事件。例如,在UIElement文档的事件部分中,您可以找到该类公开的所有事件的列表。其余课程相同。

注意

在“ 事件概述”文档中找到有关事件的更多信息

订阅

可以使用两种不同的方式来订阅NoesisGUI中的事件:有和没有code-behind。使用命令的第三种选择是将视图与模型完全分离。

直接订阅

预订事件的最简单方法是使用委托直接向事件添加回调。使用FindName可以访问该对象,因此您需要使用x:Name关键字设置所需实例的名称。例如:

<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");
};

后台代码订阅

直接预订的替代方法是使用代码隐藏类,并使用方法名称在XAML中连接事件。这些方法名称需要使用正确的事件签名在代码隐藏类中实现。例如:

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

注意

阅读扩展Noesis教程以了解有关实现代码隐藏类的更多信息

当加载XAML时,FrameworkElement公开虚拟函数ConnectEvent,该虚拟函数为每个挂钩事件调用。您需要相应地覆盖该功能。在C ++中,提供了宏NS_CONNECT_EVENT作为帮助程序,以轻松实现ConnectEvent。您必须为每个要连接的事件使用if。

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, OnButton1Click);
        NS_CONNECT_EVENT(Button, Click, OnButton2Click);
        return false;
    }

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

    void OnButton2Click(BaseComponent* sender, const RoutedEventArgs& args)
    {
        printf("Button2 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 bool ConnectEvent(object source, string eventName, string handlerName)
    {
        if (eventName == "Click" && handlerName == "OnButton1Click")
        {
            ((Button)source).Click += this.OnButton1Click;
            return true;
        }

       if (eventName == "Click" && handlerName == "OnButton2Click")
        {
            ((Button)source).Click += this.OnButton2Click;
            return true;
        }

        return false;
    }

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

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

请注意,有时使用FindName不是有效的选项,而使用代码隐藏成员函数是连接事件的唯一方法。例如,当使用DataTemplate时,无法使用FindName访问可视树中的命名元素,因为为每个项目复制了数据模板。

<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>

加载和初始化事件

在Noesis中,控件同时具有Initialized事件和Loaded事件。了解这些事件何时发生对于正确初始化任何控件类非常重要。这是这些事件如何工作的一些背景。

初始化事件

初始化时说只是一个元素被创建,其性质已全部设置,并因此这通常他们的父母之前触发对孩子。因此,当在某个元素上引发Initialized时,可能会初始化其整个子树,但不会初始化其父树。在初始化加载的子树的XAML当事件通常被解雇。此事件对应于IsInitialized属性。

不应在类的构造函数中包含代码,而应始终使用Initialized事件。

C ++

class MainWindow final: public Noesis::UserControl
{
public:
    MainWindow()
    {
        Initialized() += MakeDelegate(this, &MainWindow::OnInitialized);
        InitializeComponent();
    }
private:
    void MainWindow::InitializeComponent()
    {
        GUI::LoadComponent(this, "MainWindow.xaml");
    }

    void MainWindow::OnInitialized(BaseComponent*, const EventArgs&)
    {
        SetDataContext(MakePtr<ViewModel>());
    }
}

C#

public partial class MainWindow : UserControl
{
    public MainWindow()
    {
        this.Initialized += OnInitialized;
        this.InitializeComponent();
    }

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

    private void OnInitialized(object sender, EventArgs args)
    {
        this.DataContext = new ViewModel();
    }
}

载入事件

有时,初始化事件还不够。例如,您可能想知道一个元素的ActualWidth,但是当激发Initialized时,尚未计算ActualWidth值。或者,您可能想查看数据绑定属性的值,但是该值也尚未计算。

为了解决这个问题,Loaded事件表明不仅构建和初始化了元素,而且还在其上运行布局,绑定了数据,将其连接到View并处于呈现的边缘。到达该点时,将从树的根开始广播Loaded事件。此事件对应于IsLoaded属性。

Loaded事件对称,当从已加载元素的元素树中删除元素时,发生Unloaded事件。

注意

如果不确定使用哪个事件,请使用Loaded事件。通常是正确的选择。

相关文章

  • 教程4:NoesisGUI中的事件

    NoesisGUI中的事件 github-教程数据 NoesisGUI是一个事件驱动的框架,其中所有控件都公开了您...

  • C++教程4:NoesisGUI集成教程

    NoesisGUI集成教程 教程数据 本教程重点介绍将NoesisGUI集成到您自己的应用程序中并渲染接口所必须遵...

  • C++教程1:NoesisGUI C ++ SDK入门

    NoesisGUI C ++ SDK入门 本教程的目的是使您开始使用NoesisGUI C ++ SDK及其目录结...

  • NoesisGUI和Unity的第一步

    NoesisGUI和Unity的第一步 本教程介绍了在Unity中使用NoesisGUI的基础知识。您将学习如何开...

  • C++教程5:应用框架

    应用框架 教程数据 尽管noesisGUI可以完全集成到您的应用程序中,但是如集成教程中所示,还提供了一个Appl...

  • 教程16:拖放概述

    拖放概述 教程数据 本教程概述了NoesisGUI中的拖放支持。拖放通常是指一种数据传输方法,该方法包括使用鼠标(...

  • 教程12:扩展NoesisGUI

    扩展NoesisGUI 基于XAML的noesisGUI是一个可以以多种方式扩展的框架。例如,您可以创建自己的Co...

  • 教程20:优化NoesisGUI性能

    优化NoesisGUI性能 本部分旨在作为参考指南,介绍提高NoesisGUI性能的方法。 渲染效果 注意 为了优...

  • 教程11:样式和模板

    样式和模板 教程数据 NoesisGUI的样式和模板是指一组功能(样式,模板,触发器和情节提要),这些功能使开发人...

  • 教程3:控件介绍

    控件介绍 教程数据 NoesisGUI包含一组标准控件,使您能够快速组装传统用户界面。它们可以分为四个主要类别,这...

网友评论

      本文标题:教程4:NoesisGUI中的事件

      本文链接:https://www.haomeiwen.com/subject/uoifshtx.html