xamarin.forms - 带有 XF 的 ReactiveUI:如何为自定义控件创建命令绑定器?
问题描述
我正在使用Xamarin Forms和ReactiveUI并尝试将自定义命令从自定义 XF 控件绑定到我的视图模型。
this.BindCommand(ViewModel, vm => vm.HasChangesCommand, view => view.socket1);
我的控制 socket1 有一个 ICommand 类型的依赖属性命令。但是,我收到了错误:
“System.Exception:找不到 [ControlName] 的命令绑定器”
我想我必须为我的控件创建一个命令绑定器,但我找不到任何关于如何执行此操作的提示。是否有关于如何为Xamarin Forms
上的自定义控件创建命令活页夹的文档?
编辑:我已经看到添加第三个参数“eventName”它正在工作。但是我想知道是否有任何方法可以构建该命令绑定器,因此您无需在该调用中指定事件。
解决方案
如果您希望能够BindCommand
与自定义视图一起使用,最简单的方法是在ICommand
名为 的视图上拥有类型属性Command
。OneWayBind
按照Daniel 的建议执行 a也很容易,尽管当您习惯使用BindCommand
for 命令绑定时也很容易忘记这样做。
如果您想使用其他任何东西(事件、手势识别器等),您可以创建一个ICreatesCommandBinding
定义命令如何连接到目标对象的实现。因此,您可以执行以下操作:
public class SocketControl : ContentView
{
public static readonly BindableProperty MyCustomCommandProperty = BindableProperty.Create(
nameof(MyCustomCommand),
typeof(ICommand),
typeof(SocketControl));
public ICommand MyCustomCommand
{
get => (ICommand)GetValue(MyCustomCommandProperty);
set => SetValue(MyCustomCommandProperty, value);
}
//...
}
public sealed class SocketControlCommandBinder : ICreatesCommandBinding
{
public IDisposable BindCommandToObject(ICommand command, object target, IObservable<object> commandParameter)
{
var socket = (SocketControl)target;
// get the original value so we can restore it when the binding is disposed...
var originalValue = socket.GetValue(SocketControl.MyCustomCommandProperty);
var disposable = Disposable.Create(() => socket.SetValue(SocketControl.MyCustomCommandProperty, originalValue));
// set the control's command to the view-model's command
socket.SetValue(SocketControl.MyCustomCommandProperty, command);
return disposable;
}
public IDisposable BindCommandToObject<TEventArgs>(ICommand command, object target, IObservable<object> commandParameter, string eventName)
{
/// not shown here ...
return Disposable.Empty;
}
/// <summary>
/// Returns a positive integer when this class supports BindCommandToObject for this
/// particular Type. If the method isn't supported at all, return a non-positive integer.
/// When multiple implementations return a positive value, the host will use the one which
/// returns the highest value. When in doubt, return '2' or '0'
/// </summary>
/// <param name="type">The type to query for.</param>
/// <param name="hasEventTarget">If true, the host intends to use a custom event target.</param>
/// <returns>A positive integer if BCTO is supported, zero or a negative value otherwise</returns>
public int GetAffinityForObject(Type type, bool hasEventTarget)
{
return type.GetTypeInfo().IsAssignableFrom(typeof(SocketControl).GetTypeInfo()) ? 2 : 0;
}
}
一旦你创建了命令绑定器,你需要注册它以便 ReactiveUI 知道如何使用它。在您的 app.xaml.cs(或您创建应用程序的任何位置)中:
Splat.Locator.CurrentMutable.Register(
() => new SocketControlCommandBinder(),
typeof(ReactiveUI.ICreatesCommandBinding));
推荐阅读
- python-3.x - 使用表情符号肤色修饰符标记句子或推文
- javascript - 使用节点 js 从字符串中提取日期?
- html - CSS焦点按钮保持边框
- c# - 如何在其方法中获取结构的地址?
- cmake - 配置:错误:找不到 dvdread 所需的库 dvdread > 4.9.0
- r - 通过从 R 中的列表中提取元素来创建向量
- mysql - 在不使用 NodeJS 连接数据库的情况下对 Mysql 进行单元测试
- java - android studio 如何设置布局消失
- java - 如何修复“:compileTestJava”的执行任务失败?
- python - 有没有一种惯用的方法来使用 nix 设置 CI 回归测试?