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

时间:2013-07-22 20:47:28

标签: 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 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];
    }               
}

我需要使用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);
    }

}

是否可以做这样的事情?

1 个答案:

答案 0 :(得分:3)

  

是否有可能......

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

要做到这一点,你需要:

  • 给这个方案一个名称 - 为方便起见,我们称之为Amit-Binding,因为Method-Binding已用于Auto-ICommand绑定 - 请参阅http://mvvmcross.wordpress.com中的N = 36
  • 更充分地计算出它的规格 - 例如只是说明如何从ViewModel
  • 发布更改
  • 弄清楚如何在绑定描述中呈现Amit绑定 - 并且最好也可以解决如何在文本格式绑定中呈现它们
  • 提供一个或多个扩展方法,允许FluentBinding生成包含Amit-Binding的绑定描述 - 这将涉及使用通用参数化方法调用解析表达式
  • 可能还扩展了Tibet绑定解析器和源属性解析器类,以允许它解析这些Amit绑定的文本格式(如果您为文本版本选择了已经可解析的格式,则可能没有必要这些课程)
  • 提供源属性绑定扩展工厂,该工厂将知道何时以及如何创建这些Amit-Source绑定。

这可能听起来很费劲 - 但它确实很可行。有关如何使用插件添加INotifyChanged源绑定的示例,请参阅https://github.com/slodge/MvvmCross/tree/v3/Plugins/Cirrious/FieldBinding/Cirrious.MvvmCross.Plugins.FieldBinding - 尽管请注意,这是在不向FluentBinding或解析器添加任何新要求的情况下实现的。


或者......

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

有关Touch和Droid的示例,请参阅https://github.com/slodge/MvvmCross-Tutorials/tree/master/ApiExamples中的ObservableDictionary示例

  • Core项目包含从http://blogs.microsoft.co.il/blogs/shimmy/archive/2010/12/26/observabledictionary-lt-tkey-tvalue-gt-c.aspx复制的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();