将XAML事件订阅到其他C#文件中的事件处理程序

flvtvl50  于 2023-09-28  发布在  其他
关注(0)|答案(3)|浏览(85)

当我尝试将ToggleButton分配(订阅)到另一个文件中的事件处理程序时(例如:XAML命名为PrimaryPage.xaml,C#文件命名为不同的EventHandler.cs,而不是PrimaryPage.xaml)在同一个解决方案中,因为我想把事情分开。
我的意思是
1.在XAML中创建ToggleButton

<ToggleButton
    x:Name="PumpBTN"
    IsThreeState="False"
    Checked="PumpBTN_C"
    Unchecked="PumpBTN_U"
    Content="Pump" />

1.在PrimaryPage.xaml.cs中创建事件订阅

using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml;
using WinUI.XXXX.EventHandler; // Include EventHandler

namespace WinUI.XXXX.Views;

public partial class PrimaryPage : Page // Unsealed
{
    public PrimaryViewModel ViewModel
    {
        get;
    }

    public PrimaryPage()
    {
        ViewModel = App.GetService<PrimaryViewModel>();
        InitializeComponent();

        Event event = new Event();
        PumpBTN.Checked += event.PumpBTN_C; // Pump-checked subscription
        PumpBTN.Unchecked += event.PumpBTN_U; // Pump-unchecked subscription
    }
}

1.在EventHandler.cs中创建事件处理程序:

using System.IO.Ports;
using WinUI.XXXX.Views;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml;

namespace WinUI.XXXX.EventHandler;

public partial class Event
{
    public readonly SerialPort serial_port = new();

    public Serial()
    {
        Main();
    }

    public string Main()
    {
        // Serial port stuffs
        return 'strings' // Just for an example
    }

    public void PumpBTN_C(object sender, RoutedEventArgs e) // Event handler
    {
        // Code
    }
    public void PumpBTN_U(object sender, RoutedEventArgs e) // Event handler
    {
        // Code
    }

我想我已经做了所有我需要做的事情,我已经输入了using,后面跟着相应的名称空间,我已经订阅并创建了一个需要的事件处理程序。
我几周前才开始在WinUI3中用C#和XAML开发GUI,而且我以前没有用OOP编写的经验,所以我不知道下一步该怎么做。有什么想法吗?

1qczuiv0

1qczuiv01#

典型的方法是使用MVVM将 View 的IsChecked属性绑定到 ViewModel 中的属性:
视图

<CheckBox IsChecked="{Binding MyIsCheckedProperty}">
Pump
</CheckBox>

ViewModel

public class MyViewModel : INotifyPropertyChanged
{
    private bool myIsCheckedValue;
    public bool MyIsCheckedProperty
    {
        get => myIsCheckedValue;
        set
        {
            if (value != myIsCheckedValue)
            {
                myIsCheckedValue = value;                
                OnPropertyChanged();
                // Do other stuff
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

您可以将事件添加到MyViewModel,并在// Do other stuff点引发它以通知其他组件。或者只是调用某个方法来通知它复选框已更改。该模式的思想是“ViewModel”类应该与表示应用程序整体状态的“Model”交互并更新它。
注意,您需要确保视图的DataContext对象设置为viewModel对象。例如,使用后面的一小段代码:

public partial class MyMainWindow : Window
{
        private MainWindowViewModel mwmv;
        public MyMainWindow ()
        {
            InitializeComponent();
            DataContext = new MyViewModel;
        }
}

这通常只对根窗口执行,并使用绑定将任何其他视图与viewModel相关联。因为所有绑定都是相对于DataContextObject的,所以需要这样做。

k2arahey

k2arahey2#

根据JonasH建议:

您是否考虑过使用MVVM并绑定IsChecked-property?如果使用这个模型,你会尽可能避免代码落后,而是把它放在一个“视图模型”类中,使用绑定来同步视图和viewModel。
下面是我如何将它应用到我的代码中。
首先,我根据MVVM Design PatternEventHandler.cs(其中包含XAML ToggleButton的事件处理程序)移动到ViewModel文件夹中。
然后,我在EventHandler.cs上创建一个EventEvent函数:

using System.IO.Ports;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;

namespace WinUI.XXXX.ViewModels.Event;

public partial class EventHandler
{
    public void PumpBTN_C(object sender, RoutedEventArgs e)
    {
        // Handle the event
    }
    
    public void PumpBTN_U(object sender, RoutedEventArgs e)
    {
        // Handle the event
    }
}

确保在PrimaryPage.xaml.cs中导入必要的命名空间,然后创建一个名为“Event”的字段,该字段链接到EventHandler.cs中的EventHandler类:

using Microsoft.UI.Xaml.Controls;
using WinUI.XXXX.ViewModels;
using WinUI.XXXX.ViewModels.Event;

namespace WinUI.XXXX.Views;

public partial class PrimaryPage : Page // Unsealed
{
    EventHandler Event = new(); // Create a field named 'Event'

    public PrimaryPage()
    {
        InitializeComponent();
    }
}

之后,将XAML文件中ToggleButton上的IsChecked属性绑定到EventList函数:

<ToggleButton
    IsThreeState="False"
    Checked="{x:Bind Event.PumpBTN_C}"
    Unchecked="{x:Bind Event.PumpBTN_U}"
    Content="Pump" />

通过这种方式,您现在可以创建一个EventHandler,然后将ToggleButton绑定到完全不同的类(或文件)中的事件处理程序。
P.S.我是C# GUI开发的新手,所以如果有人有更清晰或更有效的方法来解释这个主题,请在下面提供您的见解或想法。

sxissh06

sxissh063#

事件处理程序本身 * 必须 * 在与XAML元素相同的类中定义。
你可以做的是沿着参数传递给你的其他类的方法,并在那里执行任何工作,例如:

public PrimaryPage()
{
    ViewModel = App.GetService<PrimaryViewModel>();
    InitializeComponent();

    Event event = new Event();
    PumpBTN.Checked += (s,e) => event.PumpBTN_C(s, e);
    PumpBTN.Unchecked += (s,e) => event.PumpBTN_U(s, e);
}

相关问题