这是我的解决方案,里面使用了你的代码,请尝试检查一下。
Xaml
<Window x:Class="TabControTemplatingHelpAttempt.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:tabControTemplatingHelpAttempt="clr-namespace:TabControTemplatingHelpAttempt"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<collections:ArrayList x:Key="ChartListTabs" x:Name="ChartList">
<tabControTemplatingHelpAttempt:MyChartViewModel x:Name="ChartVM_Today" ChartType="Today" ShortName="Today"/>
<tabControTemplatingHelpAttempt:MyChartViewModel x:Name="ChartVM_Week" ChartType= "Week" ShortName="This Week"/>
<tabControTemplatingHelpAttempt:MyChartViewModel x:Name="ChartVM_Month" ChartType="Month" ShortName="This Month"/>
<tabControTemplatingHelpAttempt:MyChartViewModel x:Name="ChartVM_Qtr" ChartType= "Quarter" ShortName="This Quarter"/>
<tabControTemplatingHelpAttempt:MyChartViewModel x:Name="ChartVM_Year" ChartType= "Year" ShortName="This Year"/>
<tabControTemplatingHelpAttempt:MyChartViewModel x:Name="ChartVM_Cust" ChartType= "Custom" ShortName="Custom"/>
</collections:ArrayList>
<DataTemplate x:Key="TabHeader" DataType="{x:Type tabControTemplatingHelpAttempt:MyChartViewModel}">
<TextBlock Text="{Binding ShortName}" FontSize="16" />
</DataTemplate>
<DataTemplate x:Key="TabContent" DataType="{x:Type tabControTemplatingHelpAttempt:MyChartViewModel}" >
<tabControTemplatingHelpAttempt:MyChartControl Tag="{Binding ChartType}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<TabControl ItemsSource="{StaticResource ChartListTabs}"
ItemTemplate="{StaticResource TabHeader}"
ContentTemplate="{StaticResource TabContent}"
IsSynchronizedWithCurrentItem="True"/>
</Grid></Window>
转换器代码
public class ChartType2BrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var key = (ChartType) value;
SolidColorBrush brush;
switch (key)
{
case ChartType.Today:
brush = Brushes.Tomato;
break;
case ChartType.Week:
brush = Brushes.GreenYellow;
break;
case ChartType.Month:
brush = Brushes.Firebrick;
break;
case ChartType.Quarter:
brush = Brushes.Goldenrod;
break;
case ChartType.Year:
brush = Brushes.Teal;
break;
case ChartType.Custom:
brush = Brushes.Blue;
break;
default:
throw new ArgumentOutOfRangeException();
}
return brush;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
主虚拟机
public class MyChartViewModel:BaseObservableDependencyObject
{
private ChartType _chartType;
private string _shortName;
public ChartType ChartType
{
get { return _chartType; }
set
{
_chartType = value;
OnPropertyChanged();
}
}
public string ShortName
{
get { return _shortName; }
set
{
_shortName = value;
OnPropertyChanged();
}
}
}
public enum ChartType
{
Today,
Week,
Month,
Quarter,
Year,
Custom,
}
内部用户控制 XAML
<UserControl x:Class="TabControTemplatingHelpAttempt.MyChartControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tabControTemplatingHelpAttempt="clr-namespace:TabControTemplatingHelpAttempt">
<UserControl.Resources>
<tabControTemplatingHelpAttempt:ChartType2BrushConverter x:Key="ChartType2BrushConverterKey" />
<DataTemplate x:Key="UserContentTemplateKey" DataType="{x:Type tabControTemplatingHelpAttempt:MyChartViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Fill="{Binding ChartType, Converter={StaticResource ChartType2BrushConverterKey}}"/>
<TextBlock Grid.Row="0" Text="{Binding ShortName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Grid Grid.Row="1" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ChartType, UpdateSourceTrigger=PropertyChanged}">
<Grid.DataContext>
<tabControTemplatingHelpAttempt:TabContentDataContext/>
</Grid.DataContext>
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Fill="{Binding BackgroundBrush}"/>
<TextBlock Text="{Binding Description, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid>
<ContentControl Content="{Binding }" ContentTemplate="{StaticResource UserContentTemplateKey}"/>
<!--<Grid.DataContext>
<tabControTemplatingHelpAttempt:TabContentDataContext/>
</Grid.DataContext>
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Fill="{Binding BackgroundBrush}"/>
<TextBlock Text="{Binding Code, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" VerticalAlignment="Center" HorizontalAlignment="Center"/>-->
</Grid>
请注意,如果您注释掉 Grid.DataContext 标记并在 ContentControl 标记中注释,您的内部内容将不会更新,因为它不是根据交付的 MyChartViewModel 创建的。别处
我看不出您的代码有任何问题。
内部用户控制虚拟机
public class TabContentDataContext:BaseObservableObject
{
private string _code;
private Brush _backgroundBrush;
public TabContentDataContext()
{
Init();
}
private void Init()
{
var code = GetCode();
Code = code.ToString();
BackgroundBrush = code%2 == 0 ? Brushes.Red : Brushes.Blue;
}
public virtual int GetCode()
{
return GetHashCode();
}
public string Code
{
get { return _code; }
set
{
_code = value;
OnPropertyChanged();
}
}
public Brush BackgroundBrush
{
get { return _backgroundBrush; }
set
{
_backgroundBrush = value;
OnPropertyChanged();
}
}
}
可观察的目标代码
/// <summary>
/// implements the INotifyPropertyChanged (.net 4.5)
/// </summary>
public class BaseObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
var propName = ((MemberExpression)raiser.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
更新
基础可观察依赖对象代码
/// <summary>
/// dependency object that implements the INotifyPropertyChanged (.net 4.5)
/// </summary>
public class BaseObservableDependencyObject : DependencyObject, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
var propName = ((MemberExpression)raiser.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
问候。