介绍

有这样一个需求,当用户双击Tab控件Header区域时, 希望可以直接编辑。对于WPF控件,提供一个ControlTemplate在加上一些Trigger就可以实现。效果如下:

代码

首先,我们需要给Tab Header设计一个ControlTemplate。类似一个TextBlock,双击进入编辑状态。 所以Xaml如下:

<Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:EditableTabHeaderControl}"><Grid><TextBox x:Name="PART_TabHeader" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content, Mode=TwoWay}" Visibility="Collapsed"/><TextBlock x:Name="PART_TextBlock" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content, Mode=TwoWay}"/></Grid><ControlTemplate.Triggers><Trigger Property="IsInEditMode" Value="True"><Trigger.Setters><Setter TargetName="PART_TabHeader" Property="Visibility" Value="Visible"/><Setter TargetName="PART_TextBlock" Property="Visibility" Value="Collapsed"/></Trigger.Setters></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value>
</Setter>

接下来,我们需要定义个“EditableTabHeaderControl”类,它具有控制TextBox和TextBlock的能力。如下:

namespace EditableTabHeaderDemo
{using System;using System.Windows;using System.Windows.Controls;using System.Windows.Input;using System.Windows.Threading;/// <summary>/// Header Editable TabItem/// </summary>[TemplatePart(Name = "PART_TabHeader", Type = typeof(TextBox))]public class EditableTabHeaderControl : ContentControl{/// <summary>/// Dependency property to bind EditMode with XAML Trigger/// </summary>private static readonly DependencyProperty IsInEditModeProperty = DependencyProperty.Register("IsInEditMode", typeof(bool), typeof(EditableTabHeaderControl));private TextBox textBox;private string oldText;private DispatcherTimer timer;private delegate void FocusTextBox();/// <summary>/// Gets or sets a value indicating whether this instance is in edit mode./// </summary>public bool IsInEditMode{get{return (bool)this.GetValue(IsInEditModeProperty);}set{   if (string.IsNullOrEmpty(this.textBox.Text)){this.textBox.Text = this.oldText;}this.oldText = this.textBox.Text;this.SetValue(IsInEditModeProperty, value);}}/// <summary>/// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate"/>./// </summary>public override void OnApplyTemplate(){base.OnApplyTemplate();this.textBox = this.Template.FindName("PART_TabHeader", this) as TextBox;if (this.textBox != null){this.timer = new DispatcherTimer();this.timer.Tick += TimerTick;this.timer.Interval = TimeSpan.FromMilliseconds(1);this.LostFocus += TextBoxLostFocus;this.textBox.KeyDown += TextBoxKeyDown;this.MouseDoubleClick += EditableTabHeaderControlMouseDoubleClick;}}/// <summary>/// Sets the IsInEdit mode./// </summary>/// <param name="value">if set to <c>true</c> [value].</param>public void SetEditMode(bool value){this.IsInEditMode = value;this.timer.Start();}private void TimerTick(object sender, EventArgs e){this.timer.Stop();this.MoveTextBoxInFocus();}private void MoveTextBoxInFocus(){if (this.textBox.CheckAccess()){if (!string.IsNullOrEmpty(this.textBox.Text)){this.textBox.CaretIndex = 0;this.textBox.Focus();}}else{this.textBox.Dispatcher.BeginInvoke(DispatcherPriority.Render, new FocusTextBox(this.MoveTextBoxInFocus));}}private void TextBoxKeyDown(object sender, KeyEventArgs e){if (e.Key == Key.Escape){this.textBox.Text = oldText;this.IsInEditMode = false;}else if (e.Key == Key.Enter){this.IsInEditMode = false;}}private void TextBoxLostFocus(object sender, RoutedEventArgs e){this.IsInEditMode = false;}private void EditableTabHeaderControlMouseDoubleClick(object sender, MouseButtonEventArgs e){if (e.LeftButton == MouseButtonState.Pressed){this.SetEditMode(true);}}}
}   

这里有一个问题,当控件进入编辑状态,TextBox变为可见状态时,它不能自动获得focus。一种解决办法是挂一个Timer,每1毫秒轮询一次,检查状态并控制focus。

现在就来添加一个WPF TabControl,并应用ItemContainerStyle。然后双击Header,可以编辑啦~

<Window x:Class="EditableTabHeaderDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:EditableTabHeaderDemo"Title="EditableTabHeaderDemo" Height="300" Width="500"><Window.Resources><Style x:Key="EditableTabHeaderControl" TargetType="{x:Type local:EditableTabHeaderControl}"><!-- The template specified earlier will come here !--></Style><Style x:Key="ItemContainerStyle" TargetType="TabItem"><Setter Property="HeaderTemplate"><Setter.Value><DataTemplate><local:EditableTabHeaderControlStyle="{StaticResource EditableTabHeaderControl}"><local:EditableTabHeaderControl.Content><Binding Path="Name" Mode="TwoWay"/></local:EditableTabHeaderControl.Content></local:EditableTabHeaderControl></DataTemplate></Setter.Value></Setter></Style><DataTemplate x:Key="ContentTemplate"><Grid><TextBlock HorizontalAlignment="Left" Text="{Binding Name}"/><TextBlock HorizontalAlignment="Center" Text="{Binding City}"/></Grid></DataTemplate></Window.Resources><Grid><TabControl Grid.Row="0" ItemsSource="{Binding Data}" ItemContainerStyle="{StaticResource ItemContainerStyle}" ContentTemplate="{StaticResource ContentTemplate}" /></Grid>
</Window>

开发工具

ComponentOne Studio WPF 是专为桌面应用程序开发所准备的一整套控件包,崇尚优雅和创新,以“触控优先”为设计理念,内含轻量级高性能表格控件,和大量类型丰富的2D和3D图表控件,能使开发的应用程序更富创意。

许可证

本文以及示例代码文件遵循The Code Project Open License(CPOL)。

源码下载

EditableTabHeaderSolution.zip

英文链接:Header Editable Tab Control in Wpf

WPF下可编辑Header的Tab控件实现相关推荐

  1. WPF编程,通过KeyFrame 类型制作控件线性动画的一种方法。

    WPF编程,通过KeyFrame 类型制作控件线性动画的一种方法. 原文: WPF编程,通过KeyFrame 类型制作控件线性动画的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https ...

  2. 【转】WPF从我炫系统5---基本控件的用法

    今天我来给大家讲解WPF中一些基本控件的用法,所谓基本控件,就是我们最常用用到的一些控件,通过这一节的讲解,大家会对WPF中的控件的用法有一个更深入的了解. 1.       基本控件 LABEL控件 ...

  3. WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探

    原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探 最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感觉WPF的开发思 ...

  4. MFC Tab控件的使用方法

    新建一个mfc项目a 在资源视图中,对a.rc右键,添加资源,选择Dialog,新建 之后会创建一个新的窗口,为窗口添加一个static text控件,改名为tab1 对窗口属性进行设置,Border ...

  5. TeeChart替代品,MFC下好用的高速绘图控件-(Hight-Speed Charting)

    相关链接: C++ GUI 绘图控件目录 MFC VS2010 使用TeeChart绘图控件 - 之一 - 控件和类的导入 VS2010 使用TeeChart绘图控件 - 之二 - 绘制图形(折线图, ...

  6. WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性

    原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...

  7. MFC_2.2 编辑框和文本控件

    编辑框和文本控件 1.拖控件 2.绑定变量.用户名密码编辑框控件类型.取名字.用户协议用值类型,默认CString. 设置属性.用户类型.选择mustiline TRUE. AOTO HScroll ...

  8. 似乎是发现了asp.net ajaxToolkit中TAB控件的一个BUG

    刚才想整理一下文章,不知道怎么搞的,一下子就没了,从新帖. 在一个项目当中,使用了asp.net ajaxToolkit中的TAB控件. 现在TAB中做布局,内容等等,没发现问题. 开始处理逻辑了,问 ...

  9. MFC笔记:初始化tab控件一点改进

    背景: MFC工具带有tab标签,作为导航.需要在对话框初始化时进行初始化. 一.流程简述 实现此功能需要做如下事情: 创建主对话框.多个子对话框. 子对话框需要设置属性: 外观Style为Child ...

最新文章

  1. mysql中case when then的用法
  2. 台式计算机cpu扣不下去,如果台式机的CPU太高怎么办_计算机的基本知识_IT /计算机_信息...
  3. Ninject之旅之十一:Ninject动态工厂(附程序下载)
  4. fpga中wire和reg的区别
  5. NET问答: 对 Linq 中的 Union 和 Concat 的用法困惑
  6. python数据科学实践 常象宇_Python数据科学实践
  7. Mysql 引擎 表还是库_mysql 库、表、引擎
  8. linux vi替换字符串
  9. hualinux 学生党 建议:读书就是为了社会目标做准备
  10. PT建站源码(PT服务器原程序)汇总 by 乱世狂人
  11. 系统架构设计师如何进行架构设计
  12. 如何在WPS中打开多个窗口
  13. 使用js修改图片像素颜色并保存
  14. 传美云商系统开发源码
  15. SQL注入靶场 RedTiger通关教程(level1~level10)
  16. web期末网站设计 HTML5+CSS大作业——汽车自驾游(10页) 自驾游主题HTM5网页设计作业成品
  17. arrayToJson将数组转化为json格式的js代码
  18. 数据开发岗面试绝地求生
  19. BlackSquid恶意软件分析:利用8个臭名昭著的漏洞攻击服务器,并投放挖矿恶意软件
  20. C++实验3— 个人所得税计算器

热门文章

  1. tomcat启动报错
  2. js对象转换为json格式的jquery辅助类
  3. Vmware vSphere 5.0安装和配置
  4. NIS、NFS 與 Autofs 整合應用
  5. Tungsten Fabric SDN — Netronome Agilio SmartNIC vRouter
  6. XDP/eBPF — Overview
  7. 关于stm32的数据类型
  8. 扩展资源服务器解决oauth2 性能瓶颈
  9. CentOS7 编译安装 Mariadb
  10. 12 个最佳的免费学习编程的游戏网站【转】