silverlight - silverlight wpf自定义 TabControl

  显示原文与译文双语对照的内容
95 5

我真的只是想要一个具有自定义TabItems的rtc,这是基于的的代码。

这个问题是我想的,但是下面的代码 & 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在 oab ( 而不是 uc: closabletabcontrol ) 上工作。

对于子对象,具有具有ClosableTabItems的oab的最佳方式是什么?

cheers,
Berryl

p.s 。我将为ClosableTabItem发布代码,但是我想在第一个文章中保持噪音级别。如果有帮助,请我发邮件。

时间:原作者:0个回答

53 0

下面是TabControl的屏幕截图:

enter image description here

首先,关闭按钮是一个自定义控件,允许使用不同的颜色来悬停和按下状态。

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);
 }
 }
}

主题/泛型。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的模型必须包含命令 RequestCloseCommand

两个 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; }
}

我想使用 RoutedUICommand,但是修改这种类型的命令需要花很多时间。所以这个解决方案现在是最适合我的了。

原作者:
...