2016-09-23 102 views
3

正确。因此,从WPF移动到UWP,我试图使用x:Bind来获得编译时的好处。简单的方案工作正常;但是我发现了一些我无法解决的问题。他们都是相关的,所以我想我会张贴他们在一个地方:x:绑定到UWP(通用Windows平台)

  1. 我还没有能够使Intellisense与x:Bind一起工作。我在XAML和构造函数中都设置了DataContext(以及WPF中的d:DataContext),但它不会显示成员。有没有人成功做到这一点?
  2. 然后我在UWP的某处读到DataContext总是设置为Page的代码隐藏(真的??),我需要在代码隐藏中定义一个ViewModel类型属性,然后在x:Bind中使用该属性。它是否正确?我试了一下,它的工作原理,但引起了下一个问题。
  3. 如果我在Page的代码隐藏中定义ViewModel类型的属性,则引发PropertyChanged通知的任何子属性都不会更新UI。例如,如果代码隐藏属性名为Game(的GameVM型)并且在GameVM公共属性命名Player(的GamePlayer型),并依次GamePlayer包含一个名为Name属性,则x:Bind路径看起来像{x:Bind Path=Game.Player.Name} 。但是如果我这样做,则从Name属性中引发的任何更改通知都不会更新页面的UI。

我试过的一个替代方法是在每个级别上听PropertyChanged,然后将其展开到层次结构中,但这并不奏效。即使这样做,这样做似乎有点太多了。在WPF中,像Game.Player.Name这样的子属性可以正常工作,而不必进行属性更改冒泡。或者我错过了什么?

+0

第一点:在获得建议之前,您需要始终需要构建项目。我总是建立项目,然后打开属性窗口,然后从可能的资源列表中选择绑定源 –

+0

@MatthiasHerrmann:这里不是问题。我已经多次建立了这个项目。请在下面的Monish的回答中阅读我的讨论。 – dotNET

+3

['{x:Bind}'](https://msdn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension)的默认模式是'OneTime'。在大多数情况下,'{Binding}'的默认值是'OneWay'。相关问答:[使用编译绑定(x:bind),为什么我必须调用Bindings.Update()?](http://stackoverflow.com/q/33070705/1889329)。 – IInspectable

回答

8

对。玩了几天后,搜索了很多参考资料,这里是我的发现:

  1. {x:Bind}缺乏设计时支持。该功能在wishlist上。你可能想在那里注意它。 (Visual Studio 15.4.4的新版本确实以所需的方式支持{x:Bind}中的智能感知。)
  2. {x:Bind}使用code-behind作为其DataContext。因此,您需要在代码隐藏中定义ViewModel类型的公共属性,然后在{x:Bind}路径中使用它。
  3. 正如IInspectable指出,为{x:Bind}默认模式为OneTime,不像{Binding}这在几乎所有情况下使用OneWayTwoWay。所以你需要在你的绑定中明确指定Mode。来自WPF的人应该特别关心它。
  4. 实现通知更改的子属性在{x:Bind}中工作得很好。不需要在属性层次结构中向上冒泡这些通知。我遇到的问题(问题3)是因为我的子房产属于List<T>。我将其更改为ObservableCollection<T>并开始工作。

希望这有效的道路上。

1

作为一个初学者,我唯一能回答的问题就是第一个问题。智能感知在{x:Bind}中不起作用。这些成员从未在UWP中出现过,原因不明。至于你的下两个问题,我仍在努力。

+0

任何官方的词或其他参考(Intellisense)? – dotNET

+0

https://social.msdn.microsoft.com/Forums/windowsapps/en-US/f4cdeeb6-c55a-4916-a885-83b16817fe47/no-intellisense-for-xbind?forum=wpdevelop ..希望这可以帮助 –

+0

部分你说的是不正确的。 Intellisense可以使用'{Binding}'正常工作。当我在UWP中使用'{Binding}'时,我可以在XAML中看到我的VM成员。只有'{x:Bind}'缺少智能感知。您提供的链接只会讨论'x:Bind'。 – dotNET

0

我遇到了同样的挑战,你见过。根据我的经验,为了创建编译时绑定并使用自定义对象作为属性进行更新,Page类似乎需要了解数据上下文自定义对象......您需要做的所有事情在后面的代码中引用它们,然后在XAML中绑定到它们。这创建了它所需的代码生成对象。

例如,我有一个视图模型,在XAML中绑定的CustomerViewModel。该视图模型也具有IGuest类型的属性。为了使用客户对象和有它正确更新,我在后面的代码想出了这个...

 CustomerViewModel vm 
     { 
      get 
      { 
       return (CustomerViewModel)DataContext; 
      } 
     } 
     IGuest g 
     { 
      get 
      { 
       return vm.CurrentGuest; 
      } 
     } 
     public CartGuestControl() 
     { 
      this.InitializeComponent(); 
     } 

你并不需要从代码分配任何的UI数据上下文的后面。 ..只需引用在XAML中绑定的datacontext。当绑定到任何直观的viewmodel属性时,我使用{x:Bind Path=vm.IsEditing, Mode=OneWay}。对于绑定到任何客人属性,它看起来像这样,{x:Bind Path=g.FirstName, Mode=TwoWay}.你可以为你的Player对象做这样的事情。

我遇到了x:绑定根本不会做我希望它做的事,无论我尝试什么。这通常可以通过将事情分解成具有更多特定数据上下文的较小用户控件或使用“常规”绑定来解决。

+0

感谢您分享这些信息。如果仔细看看你的建议,你的'x:Bind'仍然使用代码隐藏类作为它的'DataContext'。您所做的只是在代码隐藏中创建顶层属性,作为这些嵌套对象属性的包装。这正是我最终所做的(问题的最后一段),但是这对我而言并不适用。我现在已经找到了这个问题的根源。我会在完成挖掘后发布我的发现。 – dotNET

相关问题