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

时间:2013-08-07 23:03:28

标签: mvvmcross

在N + 1视频#34(进度)中,有一个使用CreateBindingSet()用于Android版本的示例,这不是典型的。但叙述者也简要提到了可以在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模拟器上创建绑定集的工作示例。有没有人得到这个工作?感谢。

2 个答案:

答案 0 :(得分:5)

我可以确认,叙述者说的话有点太过于轻率而没有真正想到他会怎么做......

然而,只需要一点点努力,如果你愿意,你肯定可以让CreateBindingSet在Windows中运行。

在开始之前,请考虑一些替代方案 - 特别是,我怀疑大多数人会使用Windows DependencyProperty绑定或一些手工制作的代码隐藏与PropertyChanged事件订阅。

如果您确实要将CreateBindingSet代码添加到Windows项目,那么:

  1. 将Binding和BindingEx程序集添加到您的Ui项目中 - 最简单的方法是使用nuget添加BindingEx程序包。
  2. 在Setup类中,重写InitializeLastChance并使用此机会创建MvxWindowsBindingBuilder实例并在该构建器上调用DoRegistration。这两个前两个步骤都包含在n = 35 Tibet绑定视频中 - 这是第二步,它将初始化绑定框架并帮助您超越当前的'NullReferenceException'(对于代码,请参阅BindMe.Store/Setup.cs)< / LI>
  3. 在您的视图中,您需要实现IMvxBindingContextOwner接口,并且您需要确保创建绑定上下文。您应该可以像BindingContext = new MvxBindingContext();
  4. 一样执行此操作
  5. 在您的视图中,您需要确保为绑定上下文提供与Windows DataContext相同的DataContext(视图模型)。对于电话页面,最简单的方法是将BindingContext.DataContext = this.ViewModel;添加到电话页面OnNavigatedTo方法的末尾。如果您打算在其他类中使用Mvx绑定,则步骤3和4都可以在您的BaseView中。
  6. 完成此操作后,您应该能够使用CreateBindingSet代码 - 尽管确保在创建new MvxBindingContext()之后完成所有绑定。
  7. 我现在没有配备Windows机器,所以我担心这个答案代码未经测试 - 如果它有效或无效,请再次发帖。

答案 1 :(得分: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)