我有兩個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模式留在它們各自的空間中?
但似乎這應該是一種常見的模式,並應該比上述任何一個更清晰地解決。
要求太寬泛,尤其是沒有好的[mcve](但可能會有一個)。也就是說,對於這種相互引用的場景,你的目標應該是修正代碼,以便兩個類都不依賴於其他_class_本身。您的導航應該被抽象出來,以便在運行時,知道這兩個頁面類的控制器類可以將每個頁面(該頁面應導航到的頁面)設置到另一個頁面。 –
嗨@Peter,我不相信這個例子不是M,C和V;我可以添加代碼,但模式是衆所周知的,它似乎是多餘的。話雖如此,你的建議是有幫助的。正如您所知,MVVM沒有Controller類,但我認爲最終您的建議將把所有內容放在同一個命名空間中。也許這就是最好的解決方案。雖然看起來並不高雅。 – jbhelicon
您不需要官方的「控制器」對象(儘管坦率地說,您應該不必太擔心被限制爲特定的設計模式)。代碼中的一些地方知道這兩個頁面,並負責配置/初始化它們。我的建議與名稱空間無關,也不會解決問題(您可以將這些類放在同一個名稱空間中,但仍然在兩個不同的程序集中聲明)。我不會討論[mcve]的問題,因爲MCVE的實際定義是很好理解的,並且完全沒有這裏提供的。 –