2013-08-27 51 views
0

我創建了一個BaseWindowView和我想在我的所有應用程序的基礎要使用的自定義的框架BaseViewModel如何在應用程序中使用框架中的視圖? (WPF MVVM)

BaseViewModel我有,例如,其允許我添加按鈕的方法。我可以定義一個Command,一個ButtonImageLabelString。下面是這個方法的調用示例代碼:

AddButton(OpenAnyTabCommand, "../Images/image.png", "LabelString"); 

在我BaseWindowView我有一個RibbonMenue,所有我在BaseViewModel定義了RibbonButtons都顯示:

<ItemsControl x:Name="CButtons" ItemsSource="{Binding Buttons}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel x:Name="ButtonStackPanel" Orientation="Horizontal"> 
      </StackPanel> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <ribbon:RibbonButton 
       x:Uid="Button" 
       LargeImageSource="{Binding Path=ImageString}" 
       Label="{Binding Path=LabelString}" 
       Command="{Binding Path=ButtonCommand}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

我有這在一個示例項目中,並且工作正常。現在我想將BaseWindowViewBaseViewModel外包給一個框架並從那裏使用它。

我的計劃是:在我的每個應用程序中,我想將BaseWindowView設置爲我的應用程序的MainWindow。在這個應用程序本身,我只想要一些UserControls這應該顯示爲我的BaseWindowView中的選項卡。我在BaseViewModel定義的按鈕應該調用定義Command這將打開一個新的標籤,並顯示此Command背後的ViewModel

那麼,什麼是處理我的問題的最好方法是什麼?我知道XAML中沒有「經典繼承」。我可以做一些像在框架視圖中將中的StartUpUri這樣的定義,還是「稍微有點棘手」?

作爲補充:我發現我可以在App.xaml像下面的定義DataTemplate用於TabItems(其是UserControls):

<DataTemplate DataType="{x:Type ViewModel:AnyViewModel}"> 
    <view:TabItemAny/> 
</DataTemplate> 

@Sheridan:這裏是關於BaseWindowView的問題。

+0

的問題不是很清楚:這是什麼問題?喲意識到沒有XAML繼承這樣的東西? –

+0

是的,我知道沒有「經典繼承」。我的問題是我如何做一些像視圖的繼承。我想在我的應用程序中顯示我的'Framework-View'作爲MainWindow,並且只需添加一些用於在此窗口中打開Tabs的UserControls。 – Tobias

+0

@Sheridan,這是問題 – Tobias

回答

1

好了,所以下手,讓我們將使用BaseWindowViewMainWindow

首先,在App.xaml文件,刪除的自定義ApplicationStartup性能StartupUri聲明。然後在App.xaml.cs類,添加啓動處理程序:

protected override void OnStartup(StartupEventArgs e) 
{ 
    base.OnStartup(e); 
    BaseWindowView baseWindowView = new BaseWindowView(); 
    baseWindowView.Show(); 
} 

這將打開你的Window,而不是MainWindow的。

現在到觀的繼承......如你所知,有在WPF沒有這樣的事情,但是有(種)是解決這個問題的方法。如果像你說的,所有的意見爲主,那麼我們就可以用ContentControl對象,以顯示他們UserControl,前提是相關DataTemplate對象存在。

這基本上意味着如果你想使用特定的Window作爲你的視圖的外部模板,那麼你可以添加一個ContentControl來顯示視圖。作爲一個例子,我有一個動畫Window,它顯示爲一個對話控件,帶有按鈕,我將幾個不同的UserControl連接起來,這樣它們都具有相同的整體外觀。

在XAML:

... 
<Border CornerRadius="3.5" BorderBrush="{StaticResource TransparentBlack}" 
    BorderThickness="1" Padding="1"> 
    <ContentControl Content="{Binding ViewModel, RelativeSource={RelativeSource 
     FindAncestor, AncestorType={x:Type Controls:AnimationWindow}}}" /> 
</Border> 
... 

而且在後面的Window代碼:

public static readonly DependencyProperty ViewModelProperty = DependencyProperty. 
    Register("ViewModel", typeof(BaseViewModel), typeof(AnimationWindow)); 

public BaseViewModel ViewModel 
{ 
    get { return (BaseViewModel)GetValue(ViewModelProperty); } 
    set { SetValue(ViewModelProperty, value); } 
} 

使用這個類,我可以綁定到XAML此ViewModel屬性,或者從傳遞的值設置通過構造函數。由於我所有的視圖模型都擴展了這個類,我可以將這個屬性設置爲其中的任何一個。

UPDATE >>>

使用ContentControlDataTemplate s到連接的意見/視圖模型的一點是,我們從「硬編碼的路程。我可以在每個應用程序中使用此設置,我不是而是與任何特定實現綁定在一起。

現在,如果你說你真的想使用相同視圖/視圖模型配對在您的所有不同的應用程序,那麼你應該把你的DataTemplate s到的意見/視圖模型連接在一個獨立的Resources xaml文件。這樣,你可以在這裏你需要把這個文件合併到應用程序中的App.xamlResources部分而不是當你不:

<Application.Resources> 
    <ResourceDictionary> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="ViewModelToViewDataTemplates.xaml"/> 
     <ResourceDictionary> 
      <!-- Add your normal resources here --> 
     </ResourceDictionary> 
    </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 
+0

謝謝你的回答!添加啓動處理程序正常工作。你知道我是否可以在我的'BaseViewWindow'中添加一個UserControl(它應該是一個ComboBox)的調用,但UserControl本身是在我的應用程序中定義的?此外,UserControl的DataContext應該是我的應用程序中的'ViewModel'。 – Tobias

+0

嘿。 '你是什麼意思'你知道我是否可以在我的'BaseViewWindow''中添加一個'UserControl'的調用(它應該是一個'ComboBox')? – Sheridan

+0

我想在我的'BaseViewWindow'中有''View:UserControlPerson x:Name =「UcPerson」DataContext =「{Binding Path = PersonViewModel}」/>'。但UserControl本身和PersonViewModel在應用程序中,而不在框架中。 – Tobias

相關問題