3

我有一个看起来像这样的对象结构。

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);
    }

}

有可能做这样的事情吗?

4

1 回答 1

5

是否有可能...

是的,MvvmCross 非常可扩展,因此您可以根据需要添加它。

为此,您需要:

  • 给这个方案起一个名字——现在为了方便起见,我们称它为 Amit-Binding,因为 Method-Binding 已经用于 Auto-ICommand 绑定——参见http://mvvmcross.wordpress.com中的 N=36
  • 更全面地制定它的规范 - 例如,只是澄清如何从 ViewModel 发布更改
  • 弄清楚 Amit 绑定将如何在绑定描述中呈现 - 并且可能最好也弄清楚如何在文本格式绑定中呈现它们
  • 提供一个或多个扩展方法,允许 FluentBinding 生成包含 Amit-Binding 的绑定描述 - 这将涉及使用您的通用参数化方法调用解析表达式
  • 还可能扩展西藏绑定解析器和源属性解析器类,以允许它解析这些 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 示例

  • 核心项目包括从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();
    
于 2013-07-23T02:48:21.690 回答