解决方案
我发现这个post帮我绑定了数据模板。我需要使用类似的键(Applicaiton.Current.Resources
)将数据模板添加到MainWindow.xaml.cs
:
public MainWindow()
{
InitializeComponent();
// Add the data template to the Application.Current.Resources
var _dataTemplate = (DataTemplate)Application.Current.TryFindResource("ProjectSpecificTemplate");
Application.Current.Resources.Add(_dataTemplate.DataTemplateKey, _dataTemplate);
// Add the view models to TabsViewModel.Tabs
TabsViewModel _tabs = (App.Current.Resources["Locator"] as ViewModelLocator).TabsViewModel;
_tabs.Tabs.Insert(0, (App.Current.Resources["Locator"] as ViewModelLocator).ProjectSpecificViewModel);
// Set selected tab
_tabs.SelectedTabViewModel = _tabs.Tabs[1];
}
一旦我添加了这个,视图模型就可以将自己与正确的视图联系起来。
OP
指定选项卡控件时,我通常使用以下用户控件来定义各种数据模板及其绑定:
TabsUserControl.xaml
<UserControl x:Class="DelphiaLibrary.Views.TabsUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:DelphiaLibrary.ViewModels"
xmlns:v="clr-namespace:DelphiaLibrary.Views"
mc:Ignorable="d"
DataContext="{Binding TabsViewModel, Source={StaticResource Locator}}">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Dictionary/StylesDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<TabControl ItemsSource="{Binding Tabs}"
SelectedItem="{Binding SelectedTabViewModel}">
<TabControl.Resources>
<!-- Project Specific tab -->
<DataTemplate DataType="{x:Type vm:ProjectSpecificViewModel}">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<v:ProjectSpecificUserControl />
</ScrollViewer>
</DataTemplate>
<!-- System Setup tab -->
<DataTemplate DataType="{x:Type vm:SystemSetupViewModel}">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<v:SystemSetupUserControl />
</ScrollViewer>
</DataTemplate>
</TabControl.Resources>
</TabControl>
</UserControl>
TabsViewModel.cs
public class TabsViewModel : ViewModelBase<TabsViewModel>
{
#region Initialization and Cleanup
// Default ctor
/// <summary>
/// Default TabsViewModel constructor
/// </summary>
public TabsViewModel()
{
(Application.Current.Resources["Locator"] as ViewModelLocator).TabsViewModel = this;
Tabs = new ObservableCollection<ITabViewModel>();
LoadTabInfo();
SelectedTabViewModel = Tabs.First();
}
#endregion Initialization and Cleanup
#region Properties
/// <summary>
/// Collection of tab objects
/// </summary>
public ObservableCollection<ITabViewModel> Tabs
{
get { return _Tabs; }
set
{
if (this._Tabs != value)
{
this._Tabs = value;
NotifyPropertyChanged(m => m.Tabs);
}
}
}
private ObservableCollection<ITabViewModel> _Tabs;
/// <summary>
/// SelectedTabViewModel property which also calls the TabSelected()
/// method when the SelectedTab has changed
/// </summary>
public ITabViewModel SelectedTabViewModel
{
get
{
return _SelectedTabViewModel;
}
set
{
if (this._SelectedTabViewModel != value && value != null)
{
this._SelectedTabViewModel = value;
NotifyPropertyChanged(m => m.SelectedTabViewModel);
}
}
}
private ITabViewModel _SelectedTabViewModel;
. . .
此TabsUserControl
已添加到MainWindow.xaml
文件中,并根据用户选择控制要显示的标签。 TabsUserControl
还定义了与特定视图模型关联的视图。
在上面的示例中,我有一个名为TabsViewModel
的ViewModel,它具有属性Tabs
(ObservableCollection)和SelectedTabsViewModel
(ITabViewModel)。每当SelectedTabsViewModel
更改时,都会选择并显示相应的选项卡用户控件。如果选择了ProjectSpecificViewModel
,则ProjectSpecificUserControl
会显示TabControl
。
因为我们在许多不同的项目中使用相同的设置,有许多库存标签(系统设置,关于等),我已将所有这些代码移动到库DLL文件中。但是,在将所有内容移动到DLL时,我无法再向TabsUserControl
资源添加新选项卡和视图模型。
我现在有一个使用此库DLL的新项目,我正在尝试将项目特定选项卡(不属于DLL的那个)添加到TabsUserControl
。
ProjectSpecificUserControl.xaml
<UserControl x:Class="BaseApp.Views.ProjectSpecificUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding ProjectSpecificViewModel, Source={StaticResource Locator}}">
<StackPanel>
<Label Content="Success" />
</StackPanel>
</UserControl>
我已成功将此项目特定标签视图模型添加到MainWindow.xaml.cs
后面代码中的标签集合中:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TabsViewModel _tabs = (App.Current.Resources["Locator"] as ViewModelLocator).TabsViewModel;
_tabs.Tabs.Insert(0, (App.Current.Resources["Locator"] as ViewModelLocator).ProjectSpecificViewModel);
_tabs.SelectedTabViewModel = _tabs.Tabs[0];
}
. . .
}
我还将DataTemplate
添加到MainWindow.xaml
:
<Window x:Class="BaseApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:v="clr-namespace:BaseApp.Views"
xmlns:vm="clr-namespace:BaseApp.ViewModels"
xmlns:v_dc="clr-namespace:DelphiaLibrary.Views;assembly=DelphiaLibrary"
mc:Ignorable="d"
DataContext="{Binding MainPageViewModel, Source={StaticResource Locator}}">
<Window.Resources>
<!-- ProjectSpecific tab -->
<DataTemplate x:Key="ProjectSpecificTemplate"
DataType="{x:Type vm:ProjectSpecificViewModel}">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Height="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}, Path=DataContext.MainContentHeight}">
<v:ProjectSpecificUserControl />
</ScrollViewer>
</DataTemplate>
</Window.Resources>
. . .
但无法找到将视图与视图模型相关联的方法。