0

我正在使用 MVVM 从 viewModel 动态创建选项卡。在代码中,我的尝试是保存“TabItem”的集合,该集合指定选项卡的显示方式(自定义模板)以及 ModelView 对象,然后基于 TabItem 视图 #1 / 或视图 #2 上的模型视图显示。

我目前的软件架构如下:

我的 MainWindow.xaml:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ViewModel="clr-namespace:MyApp.ViewModel" x:Class="MyApp.MainWindow"
    xmlns:Views="clr-namespace:MyApp.View"
    Height="700" Width="1000" Background="#FF1B0000" ResizeMode="NoResize">

<Window.DataContext>
    <ViewModel:TabItemViewModel/>
</Window.DataContext>
<Grid>

    <TabControl Background="Black" Margin="0,25,0,0" BorderThickness="0,0,0,0" ItemsSource="{Binding Tabs}" BorderBrush="Black" >

            <TabControl.ItemTemplate>
                <!-- this is the header template-->
                <DataTemplate>
                    <Grid Margin="0">
                        <Border Margin="0,0,0,0" 
                            Background="Black"
                            BorderBrush="Black" 
                            BorderThickness="0,0,0,0" Padding="0,0,0,0">
                            <StackPanel   Orientation="Horizontal"
                                        Margin="0,0,0,0">
                                <Image Name ="tabImage" Source="{Binding TabImage_Disabled}" />
                            </StackPanel>
                        </Border>
                    </Grid>
                    <DataTemplate.Triggers>
                        <DataTrigger Binding="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent}}" Value="True">
                            <Setter TargetName="tabImage" Property="Source" Value="{Binding TabImage_Enabled}"/>
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <!-- this is the body of the TabItem template-->
                <DataTemplate>
                    <TextBlock Text="{Binding TabContents}" Foreground="white" />
                </DataTemplate>
            </TabControl.ContentTemplate>
       </TabControl>


    </Grid>
</Window>

TabItem.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media.Imaging;
using MyApp.ViewModel;

namespace MyApp.Model
{
    public sealed class TabItem
    {
        public string TabName { get; set; }
        public BitmapImage TabImage_Enabled { get; set; }
        public BitmapImage TabImage_Disabled { get; set; }
        public BitmapImage TabImage_Background { get; set; }
        public ViewModelBase TabContents { get; set; }
    }
}

ViewModelBase.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyApp.ViewModel
{
    public class ViewModelBase : INotifyPropertyChanged
    {

         public event PropertyChangedEventHandler PropertyChanged;

         protected virtual void RaisePropertyChanged(string propertyName)
         {
              var handler = this.PropertyChanged;
              if (handler != null)
              {
                  handler(this, new PropertyChangedEventArgs(propertyName));
              }
         }
    }
}

TabItemViewModel.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows.Media.Imaging;
using MyApp.Model;

namespace MyApp.ViewModel
{
public sealed class TabItemViewModel : ViewModelBase
{

    const int NUMBER_OF_TABS = 2;

    enum enum_Tabs
    {
        Research_Tab = 0,
        Engineering_Tab = 1
    }

    Uri[] _aUrisEnabled = new Uri[NUMBER_OF_TABS];
    Uri[] _aUrisDisabled = new Uri[NUMBER_OF_TABS];
    Uri[] _aUrisBackgroundPics = new Uri[NUMBER_OF_TABS];
    BitmapImage[] _aEnabledTabImages = new BitmapImage[NUMBER_OF_TABS];
    BitmapImage[] _aDisabledTabImages = new BitmapImage[NUMBER_OF_TABS];
    BitmapImage[] _aBackgroundTabImages = new BitmapImage[NUMBER_OF_TABS];

    private ObservableCollection<TabItem> _tabs;

    public ObservableCollection<TabItem> Tabs
    {
        get { return _tabs; }
        set
        {
            _tabs = value;
            RaisePropertyChanged("Tabs");
        }
    }

    public TabItemViewModel()
    {
        Tabs = new ObservableCollection<TabItem>();


        // URIs

        // enabled pics
        _aUrisEnabled[(int)enum_Tabs.Research_Tab] = new Uri("pack://application:,,,/Images/research_enabled.png");
        _aUrisEnabled[(int)enum_Tabs.Engineering_Tab] = new Uri("pack://application:,,,/Images/engineering_enabled.png");

        // disabled pics
        _aUrisDisabled[(int)enum_Tabs.Research_Tab] = new Uri("pack://application:,,,/Images/research_disabled.png");
        _aUrisDisabled[(int)enum_Tabs.Engineering_Tab] = new Uri("pack://application:,,,/Images/engineering_disabled.png");

        // Tab backgrounds
        _aUrisBackgroundPics[(int)enum_Tabs.Research_Tab] = new Uri("pack://application:,,,/Images/research_background.png");
        _aUrisBackgroundPics[(int)enum_Tabs.Engineering_Tab] = new Uri("pack://application:,,,/Images/engineering_background.png");

        // Load all images
        for (int iImageIndex = 0; iImageIndex < NUMBER_OF_TABS; iImageIndex++)
        {
            _aEnabledTabImages[iImageIndex] = new BitmapImage(_aUrisEnabled[iImageIndex]);
            _aDisabledTabImages[iImageIndex] = new BitmapImage(_aUrisDisabled[iImageIndex]);
            _aBackgroundTabImages[iImageIndex] = new BitmapImage(_aUrisBackgroundPics[iImageIndex]);
        }


        Tabs.Add(new TabItem { TabName = "Research", TabImage_Enabled = _aEnabledTabImages[(int)enum_Tabs.Research_Tab], TabImage_Disabled = _aDisabledTabImages[(int)enum_Tabs.Research_Tab], TabImage_Background = _aBackgroundTabImages[(int)enum_Tabs.Research_Tab], TabContents = new TabResearchViewModel() });
        Tabs.Add(new TabItem { TabName = "Engineering", TabImage_Enabled = _aEnabledTabImages[(int)enum_Tabs.Engineering_Tab], TabImage_Disabled = _aDisabledTabImages[(int)enum_Tabs.Engineering_Tab], TabImage_Background = _aBackgroundTabImages[(int)enum_Tabs.Engineering_Tab], TabContents = new TabEngineeringViewModel() });
         }

     }
}

我的问题是除了视图之外,我如何指定自定义模板(对于 TabHeader,因为我显示的是图片而不是 TextBlock)。

我试过在谷歌和这个网站上搜索,但找不到使用自定义模板的解决方案。我找到了 TempleateSelector 的一些解决方案,但我不确定如何将它与 MVVM 结合使用。

我还尝试在 MainWINdow.xaml 中编写类似的内容:

        <TabControl Background="Black" Margin="0,25,0,0" BorderThickness="0,0,0,0"  ItemsSource="{Binding Tabs}" BorderBrush="Black" >

            <TabControl.Resources>
                <DataTemplate DataType="{x:Type ViewModel:TabResearchViewModel}">
                    <Views:TabResearchView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type ViewModel:TabEngineeringViewModel}">
                    <Views:TabEngineeringView />
                </DataTemplate>
            </TabControl.Resources>

        ... (removed for clarity)

我想 <TextBlock Text="{Binding TabContents}" Foreground="white" /> </DataTemplate> 用将显示“视图”(页面)的东西替换,同时绑定到选项卡集合......

非常感谢您对此事的任何帮助。先谢谢了...

4

1 回答 1

1

没关系,我自己想通了。

我的解决方案是: 1. 将视图从 Page 替换为 UserControl 2. 将“TextBlock”行替换为以下行:

<ContentPresenter Content="{Binding TabContents}" />
于 2013-08-26T10:18:44.983 回答