3

在 N+1 视频 #34(进度)中,有一个 Android 版本使用 CreateBindingSet() 的示例,并不典型。但叙述者也简单地提到,在Windows平台上也可以做到这一点。

然而,尽管我尝试了很多,但我无法将 View 的属性绑定到 Windows Phone 上的 ModelView。我总是得到一个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 模拟器上创建绑定集的工作示例。有没有人让这个工作?谢谢。

4

2 回答 2

5

我可以确认叙述者说这句话有点太轻率了,没有真正考虑过他会怎么做……

但是,只要稍加努力,您绝对可以让 CreateBindingSet 在 Windows 中工作,如果您愿意的话。

在开始之前,请考虑一些替代方案 - 特别是,我怀疑大多数人会使用 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(视图模型)。对于电话页面,最简单的方法可能只是添加BindingContext.DataContext = this.ViewModel;到电话页面OnNavigatedTo方法的末尾。如果您也打算在其他类中使用 Mvx Binding,则步骤 3 和 4 都可以在您的 BaseView 中进行。
  5. 完成此操作后,您应该能够使用 CreateBindingSet 代码 - 尽管请确保new MvxBindingContext()在创建后完成所有绑定。

我现在没有一台 Windows 机器,所以我担心这个答案代码未经测试 - 如果它有效或无效,请再次发布。

于 2013-08-08T04:30:29.373 回答
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)

于 2014-03-30T19:16:13.803 回答