如何在Windows Phone上执行CreateBindingSet()?

3
在N+1视频#34 (进展)中,提到了一个使用CreateBindingSet()的例子,适用于Android版本,这并不典型。但是叙述者也简要提到了同样可以在Windows平台上实现相同的功能。
然而,尽管我尝试了很多次,但我无法将一个View的属性绑定到它的ModelView上,在Windows Phone上总是会得到NullReferenceException。
我最接近的代码如下,包括来自ReSharper的建议。这是我的FirstView.xaml.cs:
using Cirrious.MvvmCross.Binding.BindingContext;
using Whatever.ViewModels;

namespace Whatever {

// inheriting from IMvxBindingContextOwner was suggested by ReSharper also

public partial class FirstView : BaseView, IMvxBindingContextOwner {

  public class MyBindableMediaElement
  {
        private string _theMediaSource = "whatever";                                                                                                                     
        public string TheMediaSource
        {
            get
            {
                return _theMediaSource;
            }
            set
            {
                _theMediaSource = value;
            }
        }
   }

  public FirstView()
   {
        InitializeComponent();

        _mediaElement = new MyBindableMediaElement(this.theMediaElement);

        var set = this.CreateBindingSet<FirstView, FirstViewModel>();
        // the corresponding view model has a .SongToPlay property with get/set defined
        set.Bind(_mediaElement).For(v => v.TheMediaSource).To(vm => vm.SongToPlay);
        set.Apply();
   }

    public IMvxBindingContext BindingContext { get; set; }      // this was suggested by ReSharper
}

当视图创建时,我在 MvxBaseFluentBindingDescription.cs 中遇到了 NullReferenceException 异常。具体位置如下:

    protected static string TargetPropertyName(Expression<Func<TTarget, object>> targetPropertyPath)
    {
        var parser = MvxBindingSingletonCache.Instance.PropertyExpressionParser;        // <----- exception here**
        var targetPropertyName = parser.Parse(targetPropertyPath).Print();
        return targetPropertyName;
    }

我还没有看到在Windows Phone模拟器上创建绑定集的工作示例。 有人成功做到了吗? 谢谢。

2个回答

5
我可以确认,叙述者说这句话时有些轻率,没有考虑如何实现它...
然而,如果你愿意,通过一点努力,你绝对可以在Windows上让CreateBindingSet工作。
在开始之前,请考虑一些替代方案 - 特别是我怀疑大多数人会使用Windows DependencyProperty绑定或一些手工编写的代码后台与PropertyChanged事件订阅。
如果您确实想将CreateBindingSet代码添加到Windows项目中,则需要执行以下操作:
  1. 将Binding和BindingEx程序集添加到您的Ui项目中 - 最简单的方法是使用nuget添加BindingEx包。
  2. 在您的Setup类中,重写InitializeLastChance并利用此机会创建一个MvxWindowsBindingBuilder实例,并在该构建器上调用DoRegistration。这前两个步骤在n=35西藏绑定视频中都有涉及 - 第二步将初始化绑定框架并帮助您解决当前的“NullReferenceException”问题(有关代码,请参见BindMe.Store/Setup.cs
  3. 在您的视图中,您需要实现IMvxBindingContextOwner接口,并确保创建绑定上下文。您应该能够像这样简单地完成:BindingContext = new MvxBindingContext();
  4. 在您的视图中,您需要确保绑定上下文与Windows DataContext具有相同的DataContext(视图模型)。对于Phone Page,最简单的方法可能是只需在您的phone页面的OnNavigatedTo方法末尾添加BindingContext.DataContext = this.ViewModel;。如果您打算在其他类中使用Mvx Binding,则步骤3和4都可以放在您的BaseView中。
  5. 完成这些步骤后,您应该能够使用CreateBindingSet代码 - 但请确保所有绑定都是在创建new MvxBindingContext()之后进行的。
我现在手头没有Windows机器,所以恐怕这个答案代码未经测试 - 如果它有效或无效,请再次发布。

1
谢谢你的快速回复,Stuart。根据你的建议,我已经让它正常工作了。我计划研究你提到的其他方法,但我更愿意使用BindingSet方法,因为至少它是一种可以在所有平台上使用的相同类型的代码。感谢你的帮助。 - Sarino Suon

0

我可以确认它几乎完美地工作;唯一的问题是,没有默认注册表,所以必须像这样进行完整绑定:

set.Bind(PageText).For(c => c.Text).To(vm => vm.Contents.PageText).OneTime();

为了解决这个问题,我注册了以下类,而不是注册MvxWindowsBindingBuilder。注意:我刚刚创建了这个类,需要测试。
public class UpdatedMvxWindowsBindingBuilder : MvxWindowsBindingBuilder
{
    protected override void FillDefaultBindingNames(IMvxBindingNameRegistry registry)
    {
        base.FillDefaultBindingNames(registry);



        registry.AddOrOverwrite(typeof(Button), "Command");
        registry.AddOrOverwrite(typeof(HyperlinkButton), "Command");
        //registry.AddOrOverwrite(typeof(UIBarButtonItem), "Clicked");

        //registry.AddOrOverwrite(typeof(UISearchBar), "Text");
        //registry.AddOrOverwrite(typeof(UITextField), "Text");
        registry.AddOrOverwrite(typeof(TextBlock), "Text");
        //registry.AddOrOverwrite(typeof(UILabel), "Text");
        //registry.AddOrOverwrite(typeof(MvxCollectionViewSource), "ItemsSource");
        //registry.AddOrOverwrite(typeof(MvxTableViewSource), "ItemsSource");
        //registry.AddOrOverwrite(typeof(MvxImageView), "ImageUrl");
        //registry.AddOrOverwrite(typeof(UIImageView), "Image");
        //registry.AddOrOverwrite(typeof(UIDatePicker), "Date");
        //registry.AddOrOverwrite(typeof(UISlider), "Value");
        //registry.AddOrOverwrite(typeof(UISwitch), "On");
        //registry.AddOrOverwrite(typeof(UIProgressView), "Progress");
        //registry.AddOrOverwrite(typeof(IMvxImageHelper<UIImage>), "ImageUrl");
        //registry.AddOrOverwrite(typeof(MvxImageViewLoader), "ImageUrl");

        //if (_fillBindingNamesAction != null)
        //  _fillBindingNamesAction(registry);
    }       
}

这是一个Touch绑定的框架,目前我只更新了三个控件进行测试(Button、HyperButton和TextBlock)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接