如何从不同于后面代码的 class 触发 xaml 中的事件处理程序?

How to fire off event handler in xaml from a different class than the code behind?

点击 JournalWarning 标签时,我想为 "reconnecting"

引发一个事件

我在一个 class 中有一个事件处理程序,它根据 switch case 引发不同的事件。在我的一个观点中,我想在点击标签时触发 "reconnecting" 事件。我很难弄清楚如何执行此操作,尤其是因为该事件不在后面的代码中,而是通常不同的 class。

我还不太擅长处理事件处理程序和数据绑定,但希望在我更好地工作之后,我可以更多地思考它。

在后面的代码中,我正在进行一些数据绑定,这会影响我的事件处理程序,但我还没有开始使用 TapGestureRecognizer。

我认为它可能类似于 JournalWarning.SetBinding(TapGestureRecognizer, "Reconnecting");

这是我的 JournalSocket.cs

private void Sock_DabSocketEvent(object sender, DabSocketEventHandler e)
        {
            //An event has been fired by the socket. Respond accordingly


            //Log the event to the debugger
            Debug.WriteLine($"{e.eventName} was fired with {e.data}");

            //Take action on the event
            switch (e.eventName.ToLower())
            {
                case "disconnected": //Socket disconnected
                    Sock_Disconnected(e.data);
                    break;
                case "connected": //Socket connected
                    Sock_Connected(e.data);
                    break;
                case "reconnecting": //Socket reconnecting
                    //do nothing for now
                    break;
                case "reconnected": //Socket reconnected
                    Sock_Connected(e.data);
                    break;
                case "room_error": //Error with a room
                    Sock_ErrorOccured(e.eventName, e.data);
                    break;
                case "join_error": //Error joining
                    Sock_ErrorOccured(e.eventName, e.data);
                    break;
                case "auth_error": //Error with authentication
                    Sock_ErrorOccured(e.eventName, e.data);
                    break;
                case "update": //update happened externally
                    Sock_ExternalUpdateOccured(e.eventName, e.data);
                    break;
                default:
                    break;
            }
        }

这是我的PlayerPage.xaml

<Label x:Name="JournalWarning"
                           Text="Your device has lost its connection to the journal server. Journals cannot be viewed or edited at this time. Tap here to try and reconnect."
                           Style="{StaticResource warningLabelStyle}"
                           FontSize="Medium"
                           VerticalOptions="EndAndExpand"
                           AutomationProperties.IsInAccessibleTree="true">
                        <Label.GestureRecognizers>
                            <TapGestureRecognizer Tapped="OnReconnect"/>
                        </Label.GestureRecognizers>
                    </Label>

这是我 PlayerPage.cs 背后的代码,我在其中进行了一些其他成功的数据绑定,并且认为我也可以在这里完成我想要的。虽然可能是完全错误的。

 void BindControls(bool BindToEpisode, bool BindToPlayer)
        {
            if (BindToEpisode)
            {
                //Journal
                JournalTitle.BindingContext = Episode;
                JournalTitle.SetBinding(Label.TextProperty, "title");
                JournalContent.BindingContext = journal;
                JournalContent.SetBinding(Editor.TextProperty, "Content");
                JournalContent.SetBinding(Editor.IsEnabledProperty, "IsConnected");
                JournalWarning.BindingContext = journal;
                JournalWarning.SetBinding(IsVisibleProperty, "IsDisconnected");
            }

非常感谢任何帮助!

如果你想给模型绑定Tap事件,你应该使用ICommand来实现。

使用模型-视图-视图模型 (MVVM) 模式的应用程序通常使用 ICommand 而不是直接连接事件处理程序。 TapGestureRecognizer 可以通过在代码中设置绑定轻松支持 ICommand

<Label x:Name="JournalWarning"
       Text="Your device has lost its connection to the journal server. Journals cannot be viewed or edited at this time. Tap here to try and reconnect."
       Style="{StaticResource warningLabelStyle}"
       FontSize="Medium"
       VerticalOptions="EndAndExpand"
       AutomationProperties.IsInAccessibleTree="true">
      <Label.GestureRecognizers>
           <TapGestureRecognizer Command="{Binding TapCommand}" CommandParameter="paramater"/>
      </Label.GestureRecognizers>
</Label>

可以在示例中找到此视图模型的完整代码。相关Command实现细节如下所示:

public class TapViewModel : INotifyPropertyChanged
{
    int taps = 0;
    ICommand tapCommand;
    public TapViewModel () {
        // configure the TapCommand with a method
        tapCommand = new Command (OnTapped);
    }
    public ICommand TapCommand {
        get { return tapCommand; }
    }
    void OnTapped (object s)  {
        taps++;
        Debug.WriteLine ("parameter: " + s);
    }
    //region INotifyPropertyChanged code omitted
}