![](/img/trans.png)
[英]How to use a FolderBrowserDialog from a WPF application with MVVM
[英]How can I use a view from a framework in an application? (WPF MVVM)
我已经在自定义框架中创建了BaseWindowView
和BaseViewModel
,我希望将其用作所有应用程序的基础。
在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>
我有一个示例项目,它工作正常。 现在,我想将BaseWindowView
和BaseViewModel
外包给框架,然后从那里使用它。
我的计划是:在每个应用程序中,我BaseWindowView
将BaseWindowView
设置为应用程序的MainWindow
。 在此应用程序本身中,我只想拥有一些UserControls
,这些UserControls
应在我的BaseWindowView
显示为选项卡。 我在BaseViewModel
定义的按钮应调用已定义的Command
,该Command
将打开一个新选项卡,并在此Command
之后显示ViewModel
。
那么,解决我的问题的最佳方法是什么? 我知道XAML中没有“经典继承”。 我可以像在App.xaml
中为框架视图定义StartUpUri
一样StartUpUri
,还是“有点”棘手?
另外,我发现可以在App.xaml
为TabItems
(它们是UserControls
)定义DataTemplate
,如下所示:
<DataTemplate DataType="{x:Type ViewModel:AnyViewModel}">
<view:TabItemAny/>
</DataTemplate>
@Sheridan:这是有关BaseWindowView
的问题。
好的,首先,让我们使用BaseWindowView
作为 MainWindow
:
首先,在App.xaml
文件中,从Application
定义中删除Startup
和StartupUri
属性的声明。 然后在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
类时,可以将此属性设置为任何一个。
更新>>>
使用ContentControl
和DataTemplate
连接视图/视图模型的重点是我们摆脱了“硬编码”。 我可以在每个应用程序中使用此设置,而我并不局限于使用任何特定的实现。
现在,如果您实际上要在所有不同的应用程序中使用相同的视图/视图模型配对,则应将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.