WPF定制的TabControl
问题描述:
我真的只是想有是关闭的,基于从here代码定制的TabItems一个TabControl。WPF定制的TabControl
我认为this question与我的相同,但代码& xaml的组合下面留下空的选项卡。
public class ClosableTabControl : TabControl
{
protected override DependencyObject GetContainerForItemOverride()
{
return new ClosableTabItem();
}
}
<uc:ClosableTabControl x:Name="Items" Grid.Column="1">
<uc:ClosableTabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}" />
</DataTemplate>
</uc:ClosableTabControl.ItemTemplate>
<uc:ClosableTabControl.ContentTemplate>
<DataTemplate>
<ContentControl>
<local:EmpView DataContext="{Binding ., Mode=TwoWay}"/>
</ContentControl>
</DataTemplate>
</uc:ClosableTabControl.ContentTemplate>
</uc:ClosableTabControl>
xaml在TabControl(而不是uc:ClosableTabControl)上工作。
什么是有一个有孩子ClosableTabItems一个TabControl的最佳方式?
干杯,
Berryl
附:我会发布ClosableTabItem的代码,但我想在第一篇文章中将噪音水平降低。如果有帮助,请求我发布。
答
这里是我的TabControl的截图:
所有的首先,关闭按钮是一个自定义控件,它允许使用不同颜色的悬停和按键状态。
Add -> New Item -> Custom Control -> GlyphButton
GlyphButton.cs
public class GlyphButton : Button
{
public static readonly DependencyProperty GlyphForegroundProperty = DependencyProperty.Register("GlyphForeground", typeof(Brush), typeof(GlyphButton));
public static readonly DependencyProperty HoverBackgroundProperty = DependencyProperty.Register("HoverBackground", typeof(Brush), typeof(GlyphButton));
public static readonly DependencyProperty HoverBorderBrushProperty = DependencyProperty.Register("HoverBorderBrush", typeof(Brush), typeof(GlyphButton));
public static readonly DependencyProperty HoverBorderThicknessProperty = DependencyProperty.Register("HoverBorderThickness", typeof(Thickness), typeof(GlyphButton));
public static readonly DependencyProperty HoverForegroundProperty = DependencyProperty.Register("HoverForeground", typeof(Brush), typeof(GlyphButton));
public static readonly DependencyProperty PressedBackgroundProperty = DependencyProperty.Register("PressedBackground", typeof(Brush), typeof(GlyphButton));
public static readonly DependencyProperty PressedBorderBrushProperty = DependencyProperty.Register("PressedBorderBrush", typeof(Brush), typeof(GlyphButton));
public static readonly DependencyProperty PressedBorderThicknessProperty = DependencyProperty.Register("PressedBorderThickness", typeof(Thickness), typeof(GlyphButton));
public static readonly DependencyProperty PressedForegroundProperty = DependencyProperty.Register("PressedForeground", typeof(Brush), typeof(GlyphButton));
static GlyphButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GlyphButton), new FrameworkPropertyMetadata(typeof(GlyphButton)));
}
public Brush GlyphForeground
{
get
{
return (Brush)base.GetValue(GlyphForegroundProperty);
}
set
{
base.SetValue(GlyphForegroundProperty, value);
}
}
public Brush HoverBackground
{
get
{
return (Brush)base.GetValue(HoverBackgroundProperty);
}
set
{
base.SetValue(HoverBackgroundProperty, value);
}
}
public Brush HoverBorderBrush
{
get
{
return (Brush)base.GetValue(HoverBorderBrushProperty);
}
set
{
base.SetValue(HoverBorderBrushProperty, value);
}
}
public Thickness HoverBorderThickness
{
get
{
return (Thickness)base.GetValue(HoverBorderThicknessProperty);
}
set
{
base.SetValue(HoverBorderThicknessProperty, value);
}
}
public Brush HoverForeground
{
get
{
return (Brush)base.GetValue(HoverForegroundProperty);
}
set
{
base.SetValue(HoverForegroundProperty, value);
}
}
public Brush PressedBackground
{
get
{
return (Brush)base.GetValue(PressedBackgroundProperty);
}
set
{
base.SetValue(PressedBackgroundProperty, value);
}
}
public Brush PressedBorderBrush
{
get
{
return (Brush)base.GetValue(PressedBorderBrushProperty);
}
set
{
base.SetValue(PressedBorderBrushProperty, value);
}
}
public Thickness PressedBorderThickness
{
get
{
return (Thickness)base.GetValue(PressedBorderThicknessProperty);
}
set
{
base.SetValue(PressedBorderThicknessProperty, value);
}
}
public Brush PressedForeground
{
get
{
return (Brush)base.GetValue(PressedForegroundProperty);
}
set
{
base.SetValue(PressedForegroundProperty, value);
}
}
}
主题/ Generic.xaml
<Style TargetType="{x:Type local:GlyphButton}">
<Setter Property="Width" Value="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}" />
<Setter Property="Foreground" Value="{Binding Path=GlyphForeground, RelativeSource={RelativeSource Self}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:GlyphButton}">
<Border Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Value="{Binding HoverBackground , RelativeSource={RelativeSource TemplatedParent}}" Property="Background" />
<Setter TargetName="Border" Value="{Binding HoverBorderBrush , RelativeSource={RelativeSource TemplatedParent}}" Property="BorderBrush" />
<Setter TargetName="Border" Value="{Binding HoverBorderThickness , RelativeSource={RelativeSource TemplatedParent}}" Property="BorderThickness" />
<Setter Value="{Binding HoverForeground , RelativeSource={RelativeSource TemplatedParent}}" Property="Foreground" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Value="{Binding PressedBackground , RelativeSource={RelativeSource TemplatedParent}}" Property="Background" />
<Setter TargetName="Border" Value="{Binding PressedBorderBrush , RelativeSource={RelativeSource TemplatedParent}}" Property="BorderBrush" />
<Setter TargetName="Border" Value="{Binding PressedBorderThickness , RelativeSource={RelativeSource TemplatedParent}}" Property="BorderThickness" />
<Setter Value="{Binding PressedForeground , RelativeSource={RelativeSource TemplatedParent}}" Property="Foreground" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
样式用于TabItem
。你可以把它放在任何地方,在App.xaml
或资源字典中。
TabItem的风格
<SolidColorBrush x:Key="FileTabTextKey" Color="#ffffff"/>
<SolidColorBrush x:Key="ToolWindowButtonHoverActiveKey" Color="#fffcf4"/>
<SolidColorBrush x:Key="ToolWindowButtonHoverActiveBorderKey" Color="#e5c365"/>
<SolidColorBrush x:Key="ToolWindowButtonHoverActiveGlyphKey" Color="#000000"/>
<SolidColorBrush x:Key="ToolWindowButtonDownKey" Color="#ffe8a6"/>
<SolidColorBrush x:Key="ToolWindowButtonDownBorderKey" Color="#e5c365"/>
<SolidColorBrush x:Key="ToolWindowButtonDownActiveGlyphKey" Color="#000000"/>
<LinearGradientBrush x:Key="FileTabHotGradientKey">
<GradientStop Color="#707776"/>
<GradientStop Color="#4b5c74"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="FileTabHotBorderKey" Color="#9ba7b7"/>
<SolidColorBrush x:Key="FileTabHotTextKey" Color="#ffffff"/>
<SolidColorBrush x:Key="FileTabHotGlyphKey" Color="#ced4dd"/>
<LinearGradientBrush x:Key="FileTabSelectedGradientKey" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#fffcf4"/>
<GradientStop Color="#fff3cd" Offset="0.5"/>
<GradientStop Color="#ffe8a6" Offset="0.5"/>
<GradientStop Color="#ffe8a6" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="FileTabSelectedTextKey" Color="#000000"/>
<SolidColorBrush x:Key="FileTabSelectedGlyphKey" Color="#75633d"/>
<Style x:Key="OrangeTabItem" TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border AllowDrop="true" ToolTip="{Binding Title}">
<Border Name="Border" Background="Transparent" BorderBrush="Transparent" BorderThickness="1,1,1,0" CornerRadius="2,2,0,0">
<DockPanel x:Name="TitlePanel" TextElement.Foreground="{StaticResource FileTabTextKey}">
<controls:GlyphButton x:Name="HideButton"
DockPanel.Dock="Right"
GlyphForeground="Transparent"
HoverBackground="{StaticResource ToolWindowButtonHoverActiveKey}"
HoverBorderBrush="{StaticResource ToolWindowButtonHoverActiveBorderKey}"
HoverForeground="{StaticResource ToolWindowButtonHoverActiveGlyphKey}"
PressedBackground="{StaticResource ToolWindowButtonDownKey}"
PressedBorderBrush="{StaticResource ToolWindowButtonDownBorderKey}"
PressedForeground="{StaticResource ToolWindowButtonDownActiveGlyphKey}"
HoverBorderThickness="1" PressedBorderThickness="1" Margin="3,2,3,4"
Command="{Binding RequestCloseCommand}"
CommandParameter="{Binding}"
ToolTip="Close">
<Path x:Name="CloseButtonStroke" Width="10" Height="8" Stretch="Uniform" Data="F1 M 0,0 L 2,0 5,3 8,0 10,0 6,4 10,8 8,8 5,5 2,8 0,8 4,4 0,0 Z"
Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource Self}}" />
</controls:GlyphButton>
<ContentPresenter x:Name="Content" HorizontalAlignment="Stretch" Margin="4,2,4,4" VerticalAlignment="Stretch" RecognizesAccessKey="true" ContentSource="Header" />
</DockPanel>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Value="{StaticResource FileTabHotGradientKey}" Property="Background" />
<Setter TargetName="Border" Value="{StaticResource FileTabHotBorderKey}" Property="BorderBrush" />
<Setter TargetName="TitlePanel" Value="{StaticResource FileTabHotTextKey}" Property="TextElement.Foreground" />
<Setter TargetName="HideButton" Value="{StaticResource FileTabHotGlyphKey}" Property="GlyphForeground" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="1" />
<Setter TargetName="Border" Value="{StaticResource FileTabSelectedGradientKey}" Property="Background" />
<Setter TargetName="Border" Value="{StaticResource FileTabSelectedGradientKey}" Property="BorderBrush" />
<Setter TargetName="Border" Property="BorderThickness" Value="0" />
<Setter TargetName="Border" Property="Padding" Value="0,1,0,0" />
<Setter TargetName="HideButton" Property="Margin" Value="3" />
<Setter TargetName="TitlePanel" Value="{StaticResource FileTabSelectedTextKey}" Property="TextElement.Foreground" />
<Setter TargetName="HideButton" Value="{StaticResource FileTabSelectedGlyphKey}" Property="GlyphForeground" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
现在Main Window
。我的TabControl
需要蓝色背景,但您可以根据需要更改颜色。
<Grid Background="#FF293955">
<TabControl ItemsSource="{Binding Items}" ItemContainerStyle="{StaticResource OrangeTabItem}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentControl Content="{Binding Content}"/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
最后一个重要的一句话:代表TabItem
必须包含命令两个ViewModels
public class MainViewModel
{
public MainViewModel()
{
this.Items = new ObservableCollection<TabItemViewModel>
{
new TabItemViewModel("Tab 1", OnItemRequestClose),
new TabItemViewModel("Tab item 2", OnItemRequestClose)
};
}
public ObservableCollection<TabItemViewModel> Items { get; set; }
public void OnItemRequestClose(TabItemViewModel item)
{
this.Items.Remove(item);
}
}
public class TabItemViewModel
{
public TabItemViewModel(string title, Action<TabItemViewModel> onClose)
{
this.Title = title;
this.RequestCloseCommand = new SimpleCommand(obj => onClose(this));
this.Content = "Test content " + title;
}
public string Title { get; set; }
public ICommand RequestCloseCommand { get; set; }
public object Content { get; set; }
}
RequestCloseCommand
例子我想过使用RoutedUICommand
但它会花很多时间到模型修改这种类型的命令。所以这个解决方案对我来说是最合适的。
你可以记住我的TabControl的例子,我用TabControl.ItemTemplate与被绑定到一个ViewModel命令关闭按钮。我的解决方案的优点是可以使用内部按钮关闭选项卡项目,例如保存或取消。 – vorrtex 2011-02-10 19:48:16
这是一个silverlight例子,但无论如何,这里是链接:http:// *。com/questions/4828661/silverlight-4-making-closeable-tabitems/4830314#4830314如果您已准备好使用ViewModels这样大量的数据,则可以将此示例重写为WPF。 – vorrtex 2011-02-10 19:54:07