我试图制作自己的TabControl
,这是Style
的一部分:
<Style TargetType="TabControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabPanel Grid.Row="0" Panel.ZIndex="1" Margin="0,0,4,-1" IsItemsHost="True" Background="Transparent" />
<Border Name="ContentBorder" Grid.Row="1" BorderBrush="#FFD4D4D4" BorderThickness="1" Visibility="{Binding IsChecked, ElementName=HideGrid, Converter={StaticResource Bool2VisibilityConverter}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter ContentSource="SelectedContent" />
</Grid>
</Border>
<ToggleButton IsChecked="True" Name="HideGrid" Content="Hide" Grid.Row="1" Margin="722,73,0,0" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="{Binding IsChecked, ElementName=HideGrid, Converter={StaticResource Bool2VisibilityConverter}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid Name="Item">
<Border Name="ItemBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="10,3"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="#FFD4D4D4" />
<Setter TargetName="ItemBorder" Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#FF2B579A"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="ItemBorder" Property="BorderThickness" Value="0,0,0,1"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF2B579A"/> </Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
</Style>
此样式(暂时),如下所示:忽略ToggleButton的样式:)
基本上,我尝试做的是模仿Office / Windows 8功能区:
Button
,取消选中任何标签,隐藏网格和ToggleButton
。TabPanel
,显示网格和Button
。我能做什么:
ToggleButton
。ToggleButton
醇>
问题:
选择一个check
后,我如何ToggleButton
TabItem
?
检查unselect
后,我怎样才能TabItems
ToggleButton
?
我只需要创建一个自定义的TabControl类:
public class HideableTabControl : TabControl
{
#region Variables
private Button _button;
private TabPanel _tabPanel;
private Border _border;
#endregion
static HideableTabControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(HideableTabControl), new FrameworkPropertyMetadata(typeof(HideableTabControl)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_button = Template.FindName("HideGrid", this) as Button;
_tabPanel = Template.FindName("TabPanel", this) as TabPanel;
_border = Template.FindName("ContentBorder", this) as Border;
if (_button != null)
_button.PreviewMouseDown += Button_Clicked;
if (_tabPanel != null)
foreach (TabItem tabItem in _tabPanel.Children)
{
tabItem.PreviewMouseDown += TabItem_PreviewMouseDown;
}
}
private void TabItem_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var selected = sender as TabItem;
if (selected != null)
selected.IsSelected = true;
_button.Visibility = Visibility.Visible;
_border.Visibility = Visibility.Visible;
}
private void Button_Clicked(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
foreach (TabItem child in _tabPanel.Children)
{
child.IsSelected = false;
}
_border.Visibility = Visibility.Collapsed;
_button.Visibility = Visibility.Collapsed;
}
}
这种简单的风格:
<Style TargetType="{x:Type local:HideableTabControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:HideableTabControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabPanel Name="TabPanel" Grid.Row="0" Panel.ZIndex="1" Margin="5,0,0,-1" IsItemsHost="True" Background="Transparent"/>
<Border Name="ContentBorder" Grid.Row="1" BorderBrush="#FFD4D4D4" BorderThickness="0,1" >
<ContentPresenter ContentSource="SelectedContent"/>
</Border>
<Button Name="HideGrid" Content="^ " Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Style="{DynamicResource OfficeButtonStyle}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
结果如下:
答案 0 :(得分:1)
试试这种风格:
<Style TargetType="TabControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ToggleButton IsChecked="True" x:Name="tabPanelHeader" Grid.Row="0" OverridesDefaultStyle="True" Panel.ZIndex="1" Margin="0,0,4,-1" >
<TabPanel x:Name="tabPanel" Background="Transparent" IsItemsHost="True" />
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentPresenter>
</ContentPresenter>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<Border Name="ContentBorder" Grid.Row="1" BorderBrush="#FFD4D4D4" BorderThickness="1" Visibility="{Binding IsChecked, ElementName=tabPanelHeader, Converter={StaticResource Bool2VisibilityConverter}}" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter ContentSource="SelectedContent" />
</Grid>
</Border>
<ToggleButton IsChecked="{Binding IsChecked,ElementName=tabPanelHeader}" Name="HideGrid" Content="Hide" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="{Binding IsChecked, ElementName=tabPanelHeader, Converter={StaticResource Bool2VisibilityConverter}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
答案 1 :(得分:1)
我尝试使用MVVM pattern
找到解决方案尝试以下方法:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<wpfApplication1:ViewModel/>
</Window.DataContext>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<Style TargetType="TabControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabPanel Grid.Row="0" Panel.ZIndex="1" Margin="0,0,4,-1" IsItemsHost="True" Background="Transparent" />
<Border Name="ContentBorder" Grid.Row="1" BorderBrush="#FFD4D4D4" BorderThickness="1" Visibility="{Binding IsChecked, ElementName=HideGrid, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter ContentSource="SelectedContent" />
</Grid>
</Border>
<ToggleButton
Command="{Binding Path=UnselectAllTabsCommand}"
IsChecked="{Binding Path=IsHideButtonChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Name="HideGrid" Content="Hide" Grid.Row="1" Margin="722,73,0,0" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="{Binding Path=IsHideButtonChecked, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid Name="Item">
<Border Name="ItemBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="10,3"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="#FFD4D4D4" />
<Setter TargetName="ItemBorder" Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#FF2B579A"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="ItemBorder" Property="BorderThickness" Value="0,0,0,1"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF2B579A"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
</Style>
</Window.Resources>
<Grid>
<TabControl SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding Path=ShowHideButtonCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<TabControl.Items>
<TabItem Header="Tab 1" />
<TabItem Header="Tab 2" />
<TabItem Header="Tab 3" />
</TabControl.Items>
</TabControl>
</Grid>
</Window>
namespace WpfApplication1
{
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
/// <summary>
/// The view model.
/// </summary>
internal class ViewModel : INotifyPropertyChanged
{
#region Fields
/// <summary>
/// Check if is hide button checked
/// </summary>
private bool isHideButtonChecked = true;
/// <summary>
/// The selected item
/// </summary>
private object selectedItem;
#endregion
#region Public Events
/// <summary>
/// The property changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Public Properties
/// <summary>
/// Gets or sets a value indicating whether this instance is hide button checked.
/// </summary>
/// <value>
/// <c>true</c> if this instance is hide button checked; otherwise, <c>false</c>.
/// </value>
public bool IsHideButtonChecked
{
get
{
return this.isHideButtonChecked;
}
set
{
this.isHideButtonChecked = value;
this.OnPropertyChanged();
}
}
/// <summary>
/// Gets or sets the selected item.
/// </summary>
/// <value>
/// The selected item.
/// </value>
public object SelectedItem
{
get
{
return this.selectedItem;
}
set
{
this.selectedItem = value;
this.OnPropertyChanged();
}
}
/// <summary>
/// Gets the show hide button command.
/// </summary>
/// <value>
/// The show hide button command.
/// </value>
public ICommand ShowHideButtonCommand
{
get
{
return new CommandHandler(
() =>
{
if (this.SelectedItem != null)
{
this.IsHideButtonChecked = true;
}
});
}
}
/// <summary>
/// Gets the unselect all tabs command.
/// </summary>
public ICommand UnselectAllTabsCommand
{
get
{
return new CommandHandler(() => { this.SelectedItem = null; });
}
}
#endregion
#region Methods
/// <summary>
/// The on property changed.
/// </summary>
/// <param name="propertyName">
/// The property name.
/// </param>
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
/// <summary>
/// The command handler.
/// </summary>
public class CommandHandler : ICommand
{
#region Fields
/// <summary>
/// The _action.
/// </summary>
private readonly Action _action;
/// <summary>
/// The _can execute.
/// </summary>
private readonly bool _canExecute;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="CommandHandler"/> class.
/// </summary>
/// <param name="action">
/// The action.
/// </param>
/// <param name="canExecute">
/// The can execute.
/// </param>
public CommandHandler(Action action, bool canExecute)
{
this._action = action;
this._canExecute = canExecute;
}
/// <summary>
/// Initializes a new instance of the <see cref="CommandHandler"/> class.
/// </summary>
/// <param name="action">
/// The action.
/// </param>
public CommandHandler(Action action)
: this(action, true)
{
}
#endregion
#region Public Events
/// <summary>
/// The can execute changed.
/// </summary>
public event EventHandler CanExecuteChanged;
#endregion
#region Public Methods and Operators
/// <summary>
/// The can execute.
/// </summary>
/// <param name="parameter">
/// The parameter.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public bool CanExecute(object parameter)
{
return this._canExecute;
}
/// <summary>
/// The execute.
/// </summary>
/// <param name="parameter">
/// The parameter.
/// </param>
public void Execute(object parameter)
{
this._action();
}
#endregion
}
}
请注意,您需要在项目中引用程序集:System.Windows.Interactivity,以便在引发tabControl selectionChanged事件时调用命令操作。
上面的代码已经过测试并且对我正常工作(see this screen recording in flash video)。
请尝试一下,让我知道。
我希望能帮到你。