使用MvvmCross在外部监视器上添加和绑定UIView

使用MvvmCross在外部监视器上添加和绑定UIView,mvvm,binding,xamarin.ios,mvvmcross,external-display,Mvvm,Binding,Xamarin.ios,Mvvmcross,External Display,如果检测到UIView,我将尝试在iOS中的外部监视器上显示它。我能够检测和显示一个简单的UIView使用以下代码 public void CheckForExternalDisplay() { if (UIScreen.Screens.Length > 1) { Mvx.Trace(MvxTraceLevel.Diagnostic, "Multiple screens found");

如果检测到UIView,我将尝试在iOS中的外部监视器上显示它。我能够检测和显示一个简单的UIView使用以下代码

        public void CheckForExternalDisplay()
    {
        if (UIScreen.Screens.Length > 1)
        {
            Mvx.Trace(MvxTraceLevel.Diagnostic, "Multiple screens found");
            var externalScreen = UIScreen.Screens[1];
            var rect = new RectangleF(new PointF(0, 0), externalScreen.AvailableModes.Max(m => m).Size);
            var window = new UIWindow(rect)
                {
                    Screen = UIScreen.Screens[1],
                    ClipsToBounds = true,
                    Hidden = false
                };

            var presenterView = new PresenterView(rect);
            window.AddSubview(presenterView);
        }

    }
这个视图非常简单。它包含一个UILabel和一个RadialProgress视图。大多数确定值应该是什么的繁重工作已经在另一个viewmodel上完成,该viewmodel正在更新手机屏幕上的视图。我尝试了几种技术来尝试更新外部显示器上的UIView

  • 使用MvxMessenger我尝试向新的ViewModel和视图本身传递消息。只有在我从发布ViewModel创建了一个新实例后,新ViewModel才收到消息。但是,我无法直接从视图截取消息
  • 延迟绑定和常规fluent绑定,其中绑定的viewmodel属性仅从另一个viewmodel更新
  • 试图将此视图与已与其他视图关联的viewmodel绑定
  • 一手许愿,一手拉屎。。。猜猜哪一个先填满;) 就好像UIview(如下)没有被注册/与viewmodel关联一样。我肯定我错过了什么。一如既往,我感谢你的帮助

       public sealed class PresenterView
        : MvxView
    {
        private readonly RadialProgressView _progressView;
        private readonly MvxSubscriptionToken _token;
        private IMvxMessenger _messenger;
        private UILabel _displayLabel;
    
        public PresenterView(RectangleF frame)
            : base(frame)
        {
            Frame = frame;
    
            _messenger = Mvx.Resolve<IMvxMessenger>();
            _token = _messenger.Subscribe<DisplayMessage>(OnDisplayMessageReceived);
    
            _displayLabel = new UILabel
                {
                    AdjustsFontSizeToFitWidth = true,
                    Lines = 1,
                    LineBreakMode = UILineBreakMode.TailTruncation,
                    Text = "This is a workout",
                    Font = UIFont.FromName("rayando", 96f),
                    BackgroundColor = UIColor.Clear,
                    PreferredMaxLayoutWidth = Frame.Width - 10,
                    Frame = new RectangleF(0, 0, Frame.Width - 10, frame.Height / 7),
                    TextColor = UIColor.White,
                    TextAlignment = UITextAlignment.Center,
                    AutoresizingMask = UIViewAutoresizing.All
                };
    
            AddSubview(_displayLabel);
    
            _progressView = new RadialProgressView
                {
                    Center = new PointF(Center.X, Center.Y),
                    MinValue = 0f,
                };
    
            AddSubview(_progressView);
    
            this.DelayBind(() =>
              {
            MvxFluentBindingDescriptionSet<PresenterView, PresenterViewModel> set =
                this.CreateBindingSet<PresenterView, PresenterViewModel>();
            set.Bind(_progressView).For(pv => pv.Value).To(vm => vm.ClockValue);
            set.Bind(_progressView).For(pv => pv.MaxValue).To(vm => vm.MaxProgress);
            set.Bind(_workoutLabel).To(vm => vm.DisplayText);
            set.Apply();
              }); 
        }
    
        private void OnDisplayMessageReceived(DisplayMessage obj)
        {
            _workoutLabel.Text = obj.Message;
        }
    }
    
    公共密封类PresenterView
    :MvxView
    {
    私有只读RadialProgressView\u progressView;
    私有只读MvxSubscriptionToken(令牌);
    专用IMvxMessenger\u messenger;
    专用UILabel displayLabel;
    公共演示者视图(矩形框架)
    :底座(框架)
    {
    帧=帧;
    _messenger=Mvx.Resolve();
    _令牌=_messenger.Subscribe(OnDisplayMessageReceived);
    _displayLabel=新UILabel
    {
    AdjustsFontSizeToFitWidth=true,
    行=1,
    LineBreakMode=UILineBreakMode.TailTruncation,
    Text=“这是一项训练”,
    Font=UIFont.FromName(“rayando”,96f),
    BackgroundColor=UIColor.Clear,
    PreferredMaxLayoutWidth=帧宽度-10,
    框架=新矩形F(0,0,框架宽度-10,框架高度/7),
    TextColor=UIColor.White,
    TextAlignment=UITextAlignment.Center,
    AutoresizingMask=UIViewAutoresizing.All
    };
    AddSubview(_displayLabel);
    _progressView=新的RadialProgressView
    {
    中心=新的点F(中心X,中心Y),
    最小值=0f,
    };
    添加子视图(_progressView);
    这个.DelayBind(()=>
    {
    MvxFluentBindingDescriptionSet=
    此参数为.CreateBindingSet();
    set.Bind(_progressView).For(pv=>pv.Value).To(vm=>vm.ClockValue);
    set.Bind(_progressView).For(pv=>pv.MaxValue).To(vm=>vm.MaxProgress);
    set.Bind(_workoutLabel).To(vm=>vm.DisplayText);
    set.Apply();
    }); 
    }
    接收到私有void OnDisplayMessage(DisplayMessage obj)
    {
    _workoutLabel.Text=obj.Message;
    }
    }
    

    我确实意识到我在这里包括了这两种解决方案。我确实独立地尝试了每种方法。

    从您发布的代码中,我看不到您在为视图设置数据上下文的任何地方

    在“正常mvvmcross”中:

    • MvxViewController使用其在viewDidLoad中的显示请求创建自己的DataContext(ViewModel)
    • 其他一些应用程序代码基于特定于应用程序的逻辑设置MvxView的DataContext-请参见中的n=32作为示例

    在您的代码中,我目前看不到您在哪里设置了这个-所以请尝试在某个地方设置view.DataContext

    谢谢你的帮助!我尝试按照建议设置数据上下文,但仍然没有成功。基本上,我所做的是创建一个视图实例,该实例在另一个视图的ViewDidLoad事件中显示在外部屏幕上,该视图的属性为external ViewModel。然后我将外部视图DataContext绑定到该属性,但似乎没有任何数据更新。这是因为我尝试更新的视图实际上位于不同的窗口/UI屏幕上吗?“我尝试了…然后绑定了…这是因为…”。对不起,这太难理解了。尝试查看调试跟踪,尝试在问题中包含更多代码,尝试设置断点并查看变量,尝试发布完整的repo。抱歉-我发现评论中的细节很难阅读-他们只是觉得比这里的完整问题/答案更难阅读和理解。斯图尔特-我再次感谢您的反馈!我为我在评论中放置太多细节而造成的混乱道歉。我创建了一个简单的项目,它反映了我正在努力完成的任务,但仍然收到相同的结果。我已经把这个项目推到GitHub上了。我可以在以下网站找到