2016-09-23 136 views
-1

我有兩個XAML頁面,它們是不同MVVM模式的每個部分;稱他們爲PageA和PageB。每個MVVM框架都位於不同的名稱空間和項目中,因爲它們之間沒有任何合作;稱他們爲SpaceA和SpaceB,以及ProjectA和ProjectB。XAML頁面之間的交叉導航

除了:在某些時候,SpaceA框架想要導航到PageB,而在另一個點上,SpaceB想要導航到PageA。 最明顯的挑戰是,這(不可避免的?)會導致框架之間的循環引用:

Frame.Navigate(typeof(SpaceA.PageA)); /* circular */ Frame.Navigate(typeof(SpaceB.PageB)); 

< <這個問題的原始形式沒有代碼,這可能使它過於含糊或空泛。所以,我已經添加它>>

下面是網頁A代碼:

<Page x:Class="SpaceA.PageA" ...><Button Tapped="onTap">Go to Page B</Button> 

隨着代碼隱藏

namespace SpaceA 
{ 
    public sealed partial class PageA : Page 
    { 
    private void onTap(...) { Frame.Navigate(typeof(SpaceB.PageB)); } 
    } 
} 

下面是對網頁B的代碼:

<Page x:Class="SpaceB.PageB" ...><Button Tapped="onTap">Go to Page A</Button> 

隨着CodeBehind

namespace SpaceB 
{ 
    public sealed partial class PageB : Page 
    { 
    private void onTap(...) { Frame.Navigate(typeof(SpaceA.PageA)); } 
    } 
} 

爲了簡單起見,我忽略了VM和Model元素中的所有(相當複雜的)邏輯。但是它們之間沒有耦合,除了頁面之間相互呼叫。由於循環依賴性,以上內容不會組裝。

我可以看到幾種解決方案。

我可以將它們全部組合到同一個命名空間中;但是這似乎很可惜,因爲它們只是通過這種交叉導航相結合,這就是我計劃將它們放在不同的程序集中的原因。雖然也許我在使用命名空間時過於細化?

或者我可以通過在第三個知道SpaceA和SpaceB的命名空間上面都有一個虛擬頁面來實現某些功能,以便通過該虛擬頁面完成導航。但是這看起來很難看,因爲我不得不糾正後退/前進導航堆棧,我會想象。

或者也許可以將頁面本身移動到它們自己的共享空間中,比如SpacePage,然後將其餘的MVVM模式留在它們各自的空間中?

但似乎這應該是一種常見的模式,並應該比上述任何一個更清晰地解決。

+0

要求太寬泛,尤其是沒有好的[mcve](但可能會有一個)。也就是說,對於這種相互引用的場景,你的目標應該是修正代碼,以便兩個類都不依賴於其他_class_本身。您的導航應該被抽象出來,以便在運行時,知道這兩個頁面類的控制器類可以將每個頁面(該頁面應導航到的頁面)設置到另一個頁面。 –

+0

嗨@Peter,我不相信這個例子不是M,C和V;我可以添加代碼,但模式是衆所周知的,它似乎是多餘的。話雖如此,你的建議是有幫助的。正如您所知,MVVM沒有Controller類,但我認爲最終您的建議將把所有內容放在同一個命名空間中。也許這就是最好的解決方案。雖然看起來並不高雅。 – jbhelicon

+0

您不需要官方的「控制器」對象(儘管坦率地說,您應該不必太擔心被限制爲特定的設計模式)。代碼中的一些地方知道這兩個頁面,並負責配置/初始化它們。我的建議與名稱空間無關,也不會解決問題(您可以將這些類放在同一個名稱空間中,但仍然在兩個不同的程序集中聲明)。我不會討論[mcve]的問題,因爲MCVE的實際定義是很好理解的,並且完全沒有這裏提供的。 –

回答

0

問題是我混淆了名稱空間和項目的語義。

每個MVVM在不同的命名空間中都沒有問題;問題是每個人都在一個不同的項目中。解決方法是將它們全部移到同一個項目中,理想情況下放在單獨的文件夾中以維護結構。