在代码背后创建DataTemplate绑定

时间:2017-12-11 21:05:32

标签: c# wpf xaml datatemplate

解决方案

我发现这个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>
. . .

但无法找到将视图与视图模型相关联的方法。

enter image description here

0 个答案:

没有答案