我正在使用MVVM从viewModel动态创建标签。 在代码中,我的尝试是保存“TabItem”的集合,指定标签的显示方式(自定义模板)&另外还有ModelView对象,然后基于模型视图显示在TabItem视图#1 /或视图#2上。
我目前的s / w架构如下:
My 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() });
}
}
}
我的问题ID如何指定自定义模板(对于TabHeader,因为我显示图片而不是TextBlock)以及视图。
我尝试过搜索google&amp;在这个网站上,但找不到使用自定义模板的解决方案。 我找到了一些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>
用于显示“view”(页面)的内容,同时绑定到tabs集合...
感谢您对此事的任何帮助。 谢谢你提前......
答案 0 :(得分:1)
没关系,我自己已经弄清楚了。
我的解决方案是: 1.将视图从Page替换为UserControl 2.用这一行替换“TextBlock”行:
<ContentPresenter Content="{Binding TabContents}" />