PF自定义选项卡
在WPF中,任何控件都可以自定义。
接下来自定义一个选项卡,先创建一个用户控件。控件为“TabItem”,编写页面内容样式。
代码:
<TabItem x:Class="EurasianMechanics.PublicStyles.UCTabItemWithClose"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="TabItem_Loaded">
<!--定义资源-->
<TabItem.Resources>
<!--按钮样式:用x:Key设置唯一键-->
<Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}">
<!--边框:黑色-->
<Setter Property="BorderBrush" Value="Black"></Setter>
<!--背景:白色-->
<Setter Property="Background" Value="White"></Setter>
<Setter Property="Template">
<Setter.Value>
<!--自定义模板-->
<ControlTemplate TargetType="{x:Type Button}">
<!--定义视觉树-->
<Grid>
<!--形状绘图:椭圆-->
<!-- 模板绑定(TemplateBinding):使用TemplateBinding扩展把TabItem的Stroke设置为控件的Stroke。-->
<Ellipse Width="15" Height="15" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}"></Ellipse>
<TextBlock x:Name="text" FontSize="10" Text="X" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
<!--定义触发器-->
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="true">
<!--设置背景色-->
<Setter Property="Background" Value="#FF1F5581"></Setter>
<!--设置字体颜色:白色-->
<Setter TargetName="text" Property="Foreground" Value="White"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabItem.Resources>
<!--定义样式-->
<TabItem.Style>
<!--选项卡-->
<Style TargetType="{x:Type TabItem}">
<!--边框画刷:黑色-->
<Setter Property="BorderBrush" Value="Black"></Setter>
<!--背景色:白色-->
<Setter Property="Background" Value="White"></Setter>
<!--字体:黑色-->
<Setter Property="Foreground" Value="Black"></Setter>
<!--内边距:5,0,0,0-->
<Setter Property="Padding" Value="5,0,0,0"></Setter>
<!--水平对齐方式:靠左-->
<Setter Property="HorizontalAlignment" Value="Left"></Setter>
<!--垂直对齐方式:居中-->
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Template">
<Setter.Value>
<!--定义模板:选项卡-->
<ControlTemplate TargetType="{x:Type TabItem}">
<!--定义视觉树-->
<!--边框:边框画刷BorderBrush,边框粗度BorderThickness,背景都是绑定模板样式Background-->
<Border CornerRadius="5,0,0,0" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid>
<!--定义两列-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!--定义内容:内容演示-->
<ContentPresenter Grid.Column="0" ContentSource="Header" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
<!--按钮样式Style:依赖属性绑定—》资源-->
<Button Grid.Column="1" Name="btn_Close" Style="{StaticResource CloseButtonStyle}" Click="btn_Close_Click"></Button>
</Grid>
</Border>
<!--定义触发器-->
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="#FFFF923E"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabItem.Style>
</TabItem>
效果图:
创建页面加载事件“Loaded="TabItem_Loaded"”,和按钮点击事件“Click="btn_Close_Click"”,转到后台编写代码:
private TabControl m_Parent;
/// <summary>
/// 约定的宽度
/// </summary>
private double m_ConventionWidth = 100;
//点击事件
private void btn_Close_Click(object sender, RoutedEventArgs e)
{
if (m_Parent == null)
return;
//移除自身
m_Parent.Items.Remove(this);
//移除事件
m_Parent.SizeChanged -= m_Parent_SizeChanged;
int criticalCount = (int)((m_Parent.ActualWidth - 5) / m_ConventionWidth);
//平均宽度
double perWidth = (m_Parent.ActualWidth - 5) / m_Parent.Items.Count;
foreach (UCTabItemWithClose item in m_Parent.Items)
{
if (m_Parent.Items.Count <= criticalCount)
{
item.Width = m_ConventionWidth;
}
else
{
item.Width = perWidth;
}
}
}
//页面加载事件
private void TabItem_Loaded(object sender, RoutedEventArgs e)
{
//找到父级
m_Parent = FindParentTabControl(this);
if (m_Parent != null)
Load();
}
/// <summary>
/// 递归找父级TabControl
/// </summary>
/// <param name="reference">依赖对象</param>
/// <returns>TabControl</returns>
private TabControl FindParentTabControl(DependencyObject reference)
{
DependencyObject dObj = VisualTreeHelper.GetParent(reference);
if (dObj == null)
return null;
if (dObj.GetType() == typeof(TabControl))
return dObj as TabControl;
else
return FindParentTabControl(dObj);
}
/// <summary>
/// Load
/// </summary>
private void Load()
{
//约定的宽度
double.TryParse(m_Parent.Tag.ToString(), out m_ConventionWidth);
//注册父级TabControl尺寸发生变化事件
m_Parent.SizeChanged += m_Parent_SizeChanged;
//自适应
//保持约定宽度item的临界个数
int criticalCount = (int)((m_Parent.ActualWidth - 5) / m_ConventionWidth);
if (m_Parent.Items.Count <= criticalCount)
{
//小于等于临界个数 等于约定宽度
this.Width = m_ConventionWidth;
}
else
{
//大于临界个数 每项都设成平均宽度
double perWidth = (m_Parent.ActualWidth - 5) / m_Parent.Items.Count;
foreach (UCTabItemWithClose item in m_Parent.Items)
{
item.Width = perWidth;
}
this.Width = perWidth;
}
}
/// <summary>
/// 父级TabControl尺寸发生变化
/// </summary>
private void m_Parent_SizeChanged(object sender, SizeChangedEventArgs e)
{
int criticalCount = (int)((m_Parent.ActualWidth - 5) / m_ConventionWidth);
if (m_Parent.Items.Count <= criticalCount)
{
this.Width = m_ConventionWidth;
}
else
{
double perWidth = (m_Parent.ActualWidth - 5) / m_Parent.Items.Count;
this.Width = perWidth;
}
}
在主页面编写调用该用户控件的方法:
//添加选项卡
public static void AddItem(object sender, string trname, UserControl uc)
{
bool bolWhetherBe = false;//是否存在当前选项
//判断当前选项卡的个数是否大于0
if (TC.Items.Count > 0)
{
for (int i = 0; i < TC.Items.Count; i++)
{
if (((UCTabItemWithClose)TC.Items[i]).Name == trname)
{
TC.SelectedItem = ((UCTabItemWithClose)TC.Items[i]);
bolWhetherBe = true;
break;
}
}
//是否存在当前选项
if (bolWhetherBe == false)
{
//创建子选项
UCTabItemWithClose item = new UCTabItemWithClose();//创建子选项
item.Name = trname;//名称
item.Header = string.Format(trname);//标头名称
item.Content = uc;//子选择里面的内容
item.Margin = new Thickness(0, 0, 1, 0);
item.Height = 28;
TC.Items.Add(item);//添加子选项
TC.SelectedItem = item;//选中子选项
}
}
else
{
UCTabItemWithClose item = new UCTabItemWithClose();//创造子选项
item.Name = trname;//名称
item.Header = string.Format(trname);//标头名称
item.Content = uc;//子选择里面的内容
item.Margin = new Thickness(0, 0, 1, 0);
item.Height = 28;
TC.Items.Add(item);
TC.SelectedItem = item;
}
}
在主页面写点击事件来创建选项卡:
UC_AftercarmaintenanceMain myUC_AftercaMain = new UC_AftercarmaintenanceMain();
AddItem(sender, labHospitalWork.Content.ToString() + "菜单", myUC_AftercaMain);
效果图: