0

我在一个自定义框架中创建了 aBaseWindowView和 a BaseViewModel,我想在我的所有应用程序中将其用作基础。

例如,在BaseViewModel我有一个允许我添加按钮的方法。我可以定义 a Command、 aButtonImage和 a LabelString。以下是调用此方法的示例代码:

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

在我的BaseWindowView我有一个我在RibbonMenue其中RibbonButtons定义的所有内容BaseViewModel都显示的地方:

<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>

我在一个示例项目中有这个,它工作正常。现在我想将BaseWindowViewand the外包BaseViewModel给一个框架并从那里使用它。

我的计划是:在我的每个应用程序中,我想将 设置BaseWindowViewMainWindow我的应用程序。在这个应用程序本身中,我只想有一些UserControls应该在我的BaseWindowView. 我在 中定义的按钮BaseViewModel应该调用 defined Command,它会打开一个新选项卡并显示ViewModelthis 后面Command

那么处理我的问题的最佳方法是什么?我知道 XAML 中没有“经典继承”。我可以做一些像在框架视图中定义的事情StartUpUri还是App.xaml“有点”棘手?

作为补充:我发现我可以定义DataTemplatefor the TabItems(which are UserControls),App.xaml如下所示:

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

@Sheridan:这是关于BaseWindowView.

4

1 回答 1

1

好的,首先,让我们使用您的BaseWindowView as来解决MainWindow

首先,在App.xaml文件中,从定义中删除StartupStartupUri属性的声明。Application然后在App.xaml.cs类中,添加一个启动处理程序:

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

这将打开您的Window而不是MainWindow.

现在进入视图继承......如您所知,WPF 中没有这样的东西,但有(某种)解决这个问题的方法。如果,如您所说,您的所有视图都是UserControl基于的,那么我们可以使用ContentControl对象来显示它们,前提是DataTemplate存在相关对象。

这基本上意味着,如果您想使用特定Window作为视图的外部模板,那么您可以添加 aContentControl来显示视图。例如,我有一个动画Window,它显示为带有按钮的对话控件,我将几个不同UserControl的 s 绑定到这些按钮,以便它们具有相同的整体外观。

在xml中:

...
<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); }
}

使用这个类,我可以绑定到ViewModelxaml 中的这个属性,或者从通过构造函数传入的值设置它。由于我的所有视图模型都扩展了此类BaseViewModel,因此我可以将此属性设置为其中的任何一个。

更新>>>

使用 theContentControlDataTemplates 连接视图/视图模型的意义在于我们摆脱了“硬编码”。我可以在每个应用程序中使用此设置,并且我依赖于使用任何特定的实现。

现在,如果您说您实际上想在所有不同的应用程序中使用相同的视图/视图模型配对,那么您应该将您DataTemplate的 s 用于连接视图/视图模型在一个单独的Resourcesxaml 文件中。这样,您可以将此文件合并到App.xaml Resources您需要的应​​用程序部分中,而不是在您不需要时:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="ViewModelToViewDataTemplates.xaml"/>
      <ResourceDictionary>
          <!-- Add your normal resources here -->
      </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>
于 2013-08-28T10:55:49.630 回答