2016-09-23 155 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

相關問題