2015-10-22 74 views
2

我正在做一些我從未嘗試過的事情。我正在嘗試創建動態UI並將其綁定到動態模型。換句話說,我的Web服務將發回我的UI的一個小的元數據描述,並將原始數據綁定到它。因此,在構建時,我不知道我將構建的UI是什麼,我不知道我的模型會是什麼。如果不是不可能的話,將它們綁定在一起似乎非常困難沒有ViewModel的數據綁定

MVX讓我可以直接綁定UI的模型,而它作爲一個MvxViewModel。但是,如果我直接綁定到由Web服務返回的Model,則我失去了RaisePropertyChanged()的功能,因爲它只來自MvxViewModel。

通常情況下,我會寫一個包裝模型一個ViewModel,並已全部包裹制定者調用RaisePropertyChanged()。但是,在這種情況下,我的模型是動態的,所以我不能在編譯時用ViewModel包裝它,因爲我直到運行時才知道它是什麼。

有一些很棒的技巧我可以用它來構造一個視圖模型,它可以包含任何C#模型類,併發送屬性更改事件,不知道是什麼屬性的模型類具有直到運行時?

我剛剛發現的DLR和這似乎是完美的DynamicObject,但由於蘋果的限制,它不會在Xamarin.iOS工作。

+1

我有類似的要求。我將我的動態數據存儲爲JSON對象。對於數據綁定,我將其轉換爲處理屬性更改通知的ObservableDictionary。在視圖中,我創建了一個綁定集並手動將我的視圖控件綁定到字典。它工作得很好。我不在我的電腦,但我明天會發佈一個樣本。 – Kiliman

+0

我認爲如果問題中存在一些具體代碼 - 實際查看/實驗的內容,則可以更輕鬆地查看此問題。目前我不完全確定什麼改變了你的(視圖)模型中的值 - 它總是綁定UI控件,還是其他東西? (我不確定是否知道您的更改通知將生成在哪裏) – Stuart

+0

WPF也尊重[TypeDescriptors](https://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor(v = vs。 110).aspx),因此您可以根據服務器的數據動態創建類型描述符。不知道這些邪惡的ios overlords是否會阻止反射,tho。 – Will

回答

2

我不確定我最終確定的是否支持所有可能的功能,但到目前爲止,它似乎滿足我需要的一切。

我真的很喜歡寫我自己IMvxSourceBindingFactoryExtension的想法。但是,在研究如何做到這一點時,我開始使用MvvmCross中已有的功能。我已經知道MvvmCross會兌現ObservableCollection。我不知道的是,我可以在我的綁定表達式中使用[],並且不僅可以使用整數索引器,還可以使用Dictionary上的字符串索引器。我發現MvvmCross示例代碼在其GIT回購中已經實現了ObservableDictionary。事實證明,這就是我需要解決我的問題所需的一切。

因此,我的模型包含動態屬性的靜態屬性和ObservableDictionary<string,object>,其中關鍵字是動態屬性的名稱,值是屬性的值。

我的ViewModel包裝這個模型類發送關於靜態屬性的PropertyChanged通知。由於動態屬性的Dictionary是可觀察的,MvvmCross已經處理對該字典成員的更改,包括雙向。

最後一個問題是如何在綁定表達式中綁定它。這就是在[]進來如果我ObservableDictionary屬性名稱叫做UserValues,它包含在關鍵user1的值,那麼我可以2路綁定到它通過使用:UserValues[user1],一切似乎很好地工作。

我看到的一個問題是,我現在要求我的動態數據源向我返回ObservableDictionary而不僅僅是Dictionary。這是要求太多嗎?

+1

它看起來像我可以通過使用我的'ViewModel'來解決動態數據源的'ObservableDictionary'需求,該''ViewModel'封裝了我的'Model'以在'Model'中封裝一個普通的'Dictionary'與'ObservableDictionary '。這樣''ViewModel'仍然使用'ObservableDictionary',但'Model'可以是一個普通的'Dictionary'。 – scastria

+0

相關示例代碼:使用ObservableCollection https://github.com/MvvmCross/MvvmCross-Samples/blob/6f702e5ba595b345db4366a074903a8f234f5081/ApiExamples/ApiExamples.Core/ViewModels/ViewModels.cs#L203並在此ObservableCollectionView中使用ObservableCollectionViewModel:https:/ /github.com/MvvmCross/MvvmCross-Samples/blob/6f702e5ba595b345db4366a074903a8f234f5081/ApiExamples/ApiExamples.Ios/Views/FirstView.cs#L224 –

2

沒有戲弄DynamicObject到生活在iOS上,即認爲主要方法是:

  1. 你可以改變你的web服務生成的代碼,以便它產生INotifyPropertyChanged - 我用的是做到這一點的庫 - 例如http://stacky.codeplex.com/SourceControl/latest#trunk/source/Stacky/Entities/Answer.cs - 如果您無法更改Web服務代碼生成本身,您仍然可以使用某種t4或其他模板技巧來封裝或變換生成的代碼。

  2. 你可以調查某種代碼,Web服務對象,以某種觀察到的集合的映射(Kiliman曾建議這評論)

  3. 你可以看一下某種valueconverter的(或可能valuecombiner)綁定 - 我可以很容易想象一個valueconverter,它需要一個包裝模型對象和一個字符串參數(屬性名稱),並將這兩個參數一起使用(通過一些反射)來確定要做什麼。我不太確定這個如何與嵌套的模型對象一起工作......但即使這樣做也是可能的......

  4. 你可以看看MvvmCross的某種自定義綁定擴展。這並不像聽起來那麼可怕,但需要一些反思詭計 - 瞭解可能涉及的內容看看FieldBinding插件 - https://github.com/MvvmCross/MvvmCross-Plugins/tree/master/FieldBinding

    在實際的數據綁定過程中,插件將通過IMvxSourceBindingFactoryExtension - 這將是你的機會掛接到其他一些自定義更改event(而不是INotifyPropertyChanged)。這可能需要一點實驗才能解決這個問題......特別是如果你有嵌套的對象(然後需要在綁定中進行「鏈接」)......但我認爲應該可以通過這種方式來製作一些東西。

+0

真棒迴應。這些對我來說是很好的建議。我會在這裏回覆我的結果。 – scastria

+0

我認爲其中的一個關鍵是定義了變化機制(它可能與一些可能包含Model對象的Generic類綁定,並將它們呈現爲ViewModels ...)。懷疑它會需要一些迭代才能獲得好的效果......但感覺有一些有趣的想法可以奏效。期待看到你建立的東西(也許還有你必須扔掉的東西!)。玩得開心:) – Stuart