是否可以使用Fluent API在mvvmcross中进行方法绑定?

是否可以使用Fluent API在mvvmcross中进行方法绑定?,mvvm,xamarin,mvvmcross,fluent,Mvvm,Xamarin,Mvvmcross,Fluent,我有一个像这样的对象结构 public class Model : MvxViewModel { private IDictionary<string, string> _properties; public IDictionary<string, string> Properties { get { return _properties; } } public string this[string ke

我有一个像这样的对象结构

public class Model : MvxViewModel
{    
    private IDictionary<string, string> _properties;

    public IDictionary<string, string> Properties
    {
        get { return _properties; }
    }

    public string this[string key]
    {
        get { return Get(key); }
        set { Set(key, value); ;}
    }        

    public Model()
    {
        this._properties = new Dictionary<string, string>();
    }        

    public void Set(string propertyName, string value)
    {
        if (!_properties.ContainsKey(propertyName))
        {
            _properties[propertyName].Value = value;
        }
    }

    public string Get(string propertyName)
    {
        return _properties[propertyName];
    }               
}
公共类模型:MvxViewModel
{    
私人IDictionary_财产;
公共索引属性
{
获取{return\u properties;}
}
公共字符串此[字符串键]
{
get{return get(key);}
集合{set(键,值);}
}        
公共模型()
{
这是。_properties=new Dictionary();
}        
公共无效集(字符串属性名称、字符串值)
{
if(!\u properties.ContainsKey(propertyName))
{
_属性[propertyName]。值=值;
}
}
公共字符串获取(字符串属性名称)
{
返回属性[propertyName];
}               
}
我需要使用Fluent API将此对象的信息绑定到控件。 我的控件是在代码中创建的

代码如下所示:

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.Hello);

    Model employeeModel = new Model();
    model["Id"] = 1000;
    model["FirstName"] = "Stuart";
    model["MiddleName"] = "";
    model["LastName"] = "Lodge";
    TableLayout containerLayout = this.FindViewById<TableLayout>(Resource.Id.containerLayout);
    if (containerLayout != null)
    {
        TableRow newRow = new TableRow(base.ApplicationContext);
        newRow.SetMinimumHeight(50);

        var txtFirstName = new EditText(ApplicationContext);
        txtFirstName.Hint = "First Name";

        var bindingSet = this.CreateBindingSet<HelloView, Model>();
        bindingSet.Bind(txtFirstName).For("Text").To(vm => vm.Get("FirstName"));
        bindingSet.Apply();

        newRow.AddView(txtFirstName);
        containerLayout.AddView(newRow);
    }

}
protectedoverride void OnCreate(捆绑包)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Hello);
Model employeeModel=新模型();
型号[“Id”]=1000;
型号[“名字”]=“斯图尔特”;
型号[“MiddleName”]=“”;
型号[“姓氏”]=“小屋”;
TableLayout containerLayout=this.FindViewById(Resource.Id.containerLayout);
if(containerLayout!=null)
{
TableRow newRow=新的TableRow(base.ApplicationContext);
newRow.SetMinimumHeight(50);
var txtFirstName=新编辑文本(ApplicationContext);
txtFirstName.Hint=“First Name”;
var bindingSet=this.CreateBindingSet();
bindingSet.Bind(txtFirstName).For(“Text”).To(vm=>vm.Get(“FirstName”);
bindingSet.Apply();
AddView(txtFirstName);
containerLayout.AddView(newRow);
}
}
有可能这样做吗

有没有可能

是的,MvvmCross是非常可扩展的,因此如果您愿意,可以添加它

为此,您需要:

  • 给这个方案起一个某种名称——为了方便起见,现在我们称它为Amit绑定,因为方法绑定已经用于自动ICommand绑定——请参见中的N=36
  • 更全面地确定它的规范-例如,只是澄清如何从ViewModel发布更改
  • 弄清楚Amit绑定将如何在绑定描述中呈现——也许最好也弄清楚如何在文本格式绑定中呈现它们
  • 提供一个或多个扩展方法,允许FluentBinding生成包含Amit绑定的绑定描述-这将涉及使用通用参数化方法调用解析表达式
  • 还可能扩展西藏绑定解析器和源属性解析器类,以允许它解析这些Amit绑定的文本格式(如果您为这些类的文本版本选择了一种已经可以解析的格式,则可能不需要这样做)
  • 提供一个源属性绑定扩展工厂,它将知道何时以及如何创建这些Amit源绑定
这听起来可能需要很多努力,但实际上是完全可行的。有关如何使用插件添加
INotifyChanged
源绑定的示例,请参见-但请注意,这是在没有向FluentBinding或解析器添加任何新要求的情况下实现的


或者

您可以在“普通属性”或字段(如果使用FieldBinding插件)上使用字符串索引器绑定

有关Touch和Droid中的示例,请参阅中的ObservableDictionary示例

  • 核心项目包括一个ObservableDictionary实现,该实现是从(如果不需要动态更新,则可以使用普通字典)

  • Touch UI项目包括一个流畅的绑定块,包括:

        var set = this.CreateBindingSet<ObservableDictionaryView, ObservableDictionaryViewModel>();
        set.Bind(label1).To(vm => vm.Items["One"]);
        set.Bind(label2).To(vm => vm.Items["Two"]);
        set.Bind(label3).To(vm => vm.Items["Three"]);
        set.Bind(all).To(vm => vm.ReplaceAllCommand);
        set.Bind(each).To(vm => vm.ReplaceEachCommand);
        set.Bind(makeNull).To(vm => vm.MakeNullCommand);
        set.Apply();
    
    var set=this.CreateBindingSet();
    set.Bind(label1.To)(vm=>vm.Items[“一]);
    set.Bind(label2.To)(vm=>vm.Items[“两个”]);
    set.Bind(label3.To)(vm=>vm.Items[“三]);
    set.Bind(all).To(vm=>vm.ReplaceAllCommand);
    set.Bind(each).To(vm=>vm.replaceAchCommand);
    set.Bind(makeNull).To(vm=>vm.MakeNullCommand);
    set.Apply();
    

非常感谢您的帮助,斯图尔特。我喜欢第一种方法,因为它很干净。事实上,我已经有了另一个选择,但更新不起作用,在你回答后,我知道问题是什么。我没有使用医疗器械。我将开始研究第一种方法,看看我是否能做到这一点。再次感谢您为MvvmCross用户提供的所有帮助。附带说明:当前MvvmCross(在6.4.1中测试)不支持类型安全方法绑定,如:set.Bind(buttonX).for(v=>v.Command).to(vm=>vm.DoSomething)。工作示例应该是:set.Bind(buttonX).For(v=>v.Command).To(“DoSomething”),这类似于xaml中的MethodBinding。