我正在使用MVVM從viewModel動態創建選項卡。 在代碼中,我的嘗試是保存「TabItem」的集合,該選項指定選項卡如何出現(自定義模板)&另外還有ModelView對象,然後基於模型視圖顯示在TabItem視圖#1 /或視圖#2上。通過WPF中的MVVM將不同的模型視圖和視圖綁定到每個TabItem
我當前的S/W體系結構如下:
我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,因爲im顯示圖片而不是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>
的東西,會顯示「視圖」(頁),同時結合標籤集合...
希望對任何事情有所幫助。 先進的感謝...