繁体   English   中英

如何在应用程序的框架中使用视图? (WPF MVVM)

[英]How can I use a view from a framework in an application? (WPF MVVM)

我已经在自定义框架中创建了BaseWindowViewBaseViewModel ,我希望将其用作所有应用程序的基础。

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

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

在我的BaseWindowView我有一个RibbonMenue ,其中RibbonButtons了我在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外包给框架,然后从那里使用它。

我的计划是:在每个应用程序中,我BaseWindowViewBaseWindowView设置为应用程序的MainWindow 在此应用程序本身中,我只想拥有一些UserControls ,这些UserControls应在我的BaseWindowView显示为选项卡。 我在BaseViewModel定义的按钮应调用已定义的Command ,该Command将打开一个新选项卡,并在此Command之后显示ViewModel

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

另外,我发现可以在App.xamlTabItems (它们是UserControls )定义DataTemplate ,如下所示:

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

@Sheridan:这是有关BaseWindowView的问题。

好的,首先,让我们使用BaseWindowView 作为 MainWindow

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

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

这将打开您的Window而不是MainWindow

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

这基本上意味着,如果要使用特定的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属性,也可以从通过构造函数传递的值中进行设置。 当我所有的视图模型都扩展了BaseViewModel类时,可以将此属性设置为任何一个。

更新>>>

使用ContentControlDataTemplate连接视图/视图模型的重点是我们摆脱了“硬编码”。 我可以在每个应用程序中使用此设置,而我并不局限于使用任何特定的实现。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM