【问题标题】:Execute ReactiveUI Command from Event in Xamarin Forms从 Xamarin 表单中的事件执行 ReactiveUI 命令
【发布时间】:2021-06-06 17:42:50
【问题描述】:

我在 Xamarin 表单页面中有输入字段,我想在用户完成向其中输入文本时触发 ReactiveUI 命令。我正在使用 ReactiveUI.Events.XamForms 并尝试根据 Unfocused 事件触发命令,但我不确定如何设置命令以使其正常工作。

这是我的 XAML:

<?xml version="1.0" encoding="utf-8" ?>
<rxui:ReactiveContentPage
  x:Class="XamarinReactiveUISwipeView.MainPage"
  x:TypeArguments="vm:MainPageViewModel"          
  xmlns:vm="clr-namespace:XamarinReactiveUITest.ViewModel;assembly=XamarinReactiveUITest"
  xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  xmlns:ios="clr- namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" 
  xmlns="http://xamarin.com/schemas/2014/forms"
    ios:Page.UseSafeArea="true">
    <StackLayout>
        <StackLayout Margin="10,0,0,0" Orientation="Horizontal">
            <Label Text="Task ID: " />
            <Entry x:Name="EntryTaskID" />
        </StackLayout>
        <StackLayout Margin="10,0,0,0" Orientation="Horizontal">
            <Label Text="Task Name: " />
            <Entry x:Name="EntryTaskName" />
        </StackLayout>
    </StackLayout>
</rxui:ReactiveContentPage>

这是我的代码:

public partial class MainPage : ReactiveContentPage<MainPageViewModel>
{
    public MainPage()
    {
        InitializeComponent();
        ViewModel = new MainPageViewModel();

        this.WhenActivated(disposable =>
        {
            this.Bind(ViewModel, vm => vm.TheTaskItem.TaskID, page => page.EntryTaskID.Text)
            .DisposeWith(disposable);
            this.Bind(ViewModel, vm => vm.TheTaskItem.TaskName, page => page.EntryTaskName.Text)
            .DisposeWith(disposable);
            EntryTaskName.Events().Unfocused.InvokeCommand(ViewModel, vm => vm.TheCommand);
        });
    }        
}

这是我的模型:

public class TaskItem 
{
    public TaskItem() { }

    public string TaskID { get; set; }
    public string TaskName { get; set; }        
}

这是我的视图模型:

public class MainPageViewModel : ReactiveObject
{                

    public MainPageViewModel()
    {
        TheTaskItem = new TaskItem { TaskID = "1", TaskName = "TheTaskName" };

        TheCommand = ReactiveCommand.Create<FocusEventArgs, Unit>(ExecuteTheCommand);                        
    }        

    public ReactiveCommand<FocusEventArgs, Unit> TheCommand { get; }

    private void ExecuteTheCommand(FocusEventArgs args)
    {
        //do something
    }                              

    private TaskItem _theTaskItem;

    public TaskItem TheTaskItem
    {
        get => _theTaskItem;
        set => this.RaiseAndSetIfChanged(ref _theTaskItem, value);
    }
    
}

在上面的视图模型中,它不会编译,但我不知道如何设置 ExecuteTheCommand 方法。错误是:

'void MainPageViewModel.ExecuteTheCommand(FocusEventArgs)' 的返回类型错误

但在查看示例时,看起来返回 void 的方法使用 Unit 类型。

我需要在这里做什么才能正确设置命令以使其正常工作?

【问题讨论】:

  • ReactiveCommand 的格式为ReactiveCommand.Create&lt;TInput, TOutput&gt;TOutput 是返回类型。鉴于您的声明,ExecuteTheCommand 必须返回 Unit。如果这不是您想要的,那么也许您想要...Create&lt;TInput&gt; 在您拥有&lt;FocusEventArgs, Unit&gt; 的两个地方,更改为&lt;FocusEventArgs&gt;。这个声明意味着返回类型是void
  • 好的,我首先尝试在两个地方将 更改为 ,但是当我更改 public ReactiveCommand TheCommand { get; } to public ReactiveCommand TheCommand { get; },错误转向“非泛型类型'ReactiveCommand'不能与类型参数一起使用”。但是当我将这两种类型都保留下来并且只将 Create 更改为具有 时,它起作用了。

标签: xamarin.forms command reactiveui


【解决方案1】:

在上面的评论中,OP 说如果发生变化,这会起作用:

TheCommand = ReactiveCommand.Create<FocusEventArgs, Unit>(ExecuteTheCommand);

到:

TheCommand = ReactiveCommand.Create<FocusEventArgs>(ExecuteTheCommand);

出乎意料的是,保存Create 结果的变量类型没有使用相同的泛型类型签名。它必须是:

public ReactiveCommand<FocusEventArgs, Unit> TheCommand { get; }

根据 Rodney Littles 在评论中的链接中的文档,Unit 用于表示“void return type”。 (通用类型“TOutput”将为“void”;但“void”不是有效的通用类型。)

【讨论】:

  • 是的,没错。非常感谢您的帮助。
  • @Rodney Littles:是的,我已经阅读了那个例子和许多其他例子,但至少对我来说并不清楚,当调用像上面的 ExecuteTheCommand 函数这样的另一个函数时,它只有 TInput,但 TheCommand 将同时具有 TInput 和 TOutput。在我提交这个问题之前,我最初是从 TheCommand 定义中删除 TOutput 开始的,这就是立即给我的编译器错误,所以我没想到将 TOutput 留在那里而不是另一行。跨度>
  • 我想我链接文档的目的是弄清楚为什么它不清楚?使用 InvokeCommand 键入时会遇到一些运行时问题,与此类似。不幸的是,您只需要在定义 Create 时密切注意,以确保您只提供您打算使用的泛型类型。
  • @RodneyLittles - 导致 VinceL 错过正确解决方案的原因是使用 Unit 表示“void return type”。我自己以前从未见过这个 - 它是 ReactiveUI 独有的吗?它具有意想不到的后果,Create 所需的泛型类型 &lt;FocusEventArgs&gt; 与保存 Create 结果的变量所需的泛型类型 &lt;FocusEventArgs, Unit&gt; 不同。恕我直言,这种差异非常不寻常,而且相当令人困惑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2021-01-28
  • 2013-11-25
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多