原文:WPF中自动增加行(动画)的TextBox

WPF中自动增加行(动画)的TextBox

WPF中的Textbox控件是可以自动换行的,只要设置TextWrapping属性为”Wrap”即可,但是存在一个问题:Textbox的高度是固定的,当输入文本过多时就会出现如下情况。

Textbox虽然没有自动增加高度的属性,但是我们可以通过设置来实现这一个功能。相关xaml代码如下

  1. <Grid VerticalAlignment="Top" HorizontalAlignment="Left" Width="36" Height="100">
  2. <TextBox x:Name="textBox" TextWrapping="Wrap" VerticalAlignment="Top" />
  3. </Grid>

效果如下

这里需要注意的是

  • 如果设置了textBox的Width、Height或者Margin属性,那么此textBox的大小就已经限制死了,不会自动增加,会出现上图中的情况。
  • 如果想设置textBox的大小和位置,需要把textBox放在一个Grid中,通过Grid的属性来控制textBox(上文中xaml文件中的方法)

其实到此为止所需要的功能已经实现了,但是为了让让textbox更美观,我加了一个动画

效果如下:

表面上看是一个textbox,其实是一个Grid加上2个textBox(一个显示,一个隐藏),xaml代码如下

  1. <Grid>
  2. <TextBox x:Name="txtVisible" TextWrapping="Wrap"/>
  3. <TextBox x:Name="txtHidden" TextWrapping="Wrap" Visibility="Hidden" VerticalAlignment="Top"/>
  4. </Grid>

Grid是用来控制textbox的大小的,两个textbox中,显示的那个用于输入文字,隐藏的用于触发动画。原理如下

在txtVisible中输入文字的同时,txtVisible把text传递给txtHidden,当txtHidden中的内容已经满一行时,会触发SizeChange事件,这个事件再触发txtVisible高度变化动画。代码如下

  1. public partial class txt : UserControl
  2. {
  3. private HeightAnimation anim;
  4. private double _animationDuration;
  5. public txt()
  6. {
  7. InitializeComponent();
  8. // Initialize the animation
  9. anim = new HeightAnimation(this);
  10. AnimationDuration = 500; //default value
  11. // Add the handlers to the required events
  12. txtHidden.SizeChanged += TxtHidden_SizeChanged;
  13. txtVisible.TextChanged += TxtVisible_TextChanged;
  14. }
  15. /// <summary>
  16. /// Gets or sets a value indicating whether the control is animated on loaded.
  17. /// </summary>
  18. public bool AnimateOnLoaded { get; set; } = false;
  19. /// <summary>
  20. /// Gets or sets a value indicating whether the control is animated.
  21. /// </summary>
  22. public bool IsAnimated { get; set; } = true;
  23. /// <summary>
  24. /// Gets or sets the duration of the animation.
  25. /// </summary>
  26. public double AnimationDuration
  27. {
  28. get { return _animationDuration; }
  29. set
  30. {
  31. _animationDuration = value;
  32. anim.Duration = new Duration(TimeSpan.FromMilliseconds(value));
  33. }
  34. }
  35. /// <summary>
  36. /// Gets or sets the text contents of the AnimatedTextBox.
  37. /// </summary>
  38. public string Text
  39. {
  40. get { return txtHidden.Text; }
  41. set
  42. {
  43. txtHidden.Text = value;
  44. txtVisible.Text = value;
  45. }
  46. }
  47. private void TxtVisible_TextChanged(object sender, TextChangedEventArgs e)
  48. {
  49. // When the user's writing in txtVisible, we copy the text to txtHidden
  50. txtHidden.Text = txtVisible.Text;
  51. }
  52. private void TxtHidden_SizeChanged(object sender, SizeChangedEventArgs e)
  53. {
  54. OnHeightChanged(e.PreviousSize.Height, e.NewSize.Height);
  55. }
  56. /// <summary>
  57. /// To execute when the txtHidden's Height has changed.
  58. /// </summary>
  59. private void OnHeightChanged(double previousHeight, double newHeight)
  60. {
  61. //Animation type, increase txtVisible's height or decrease
  62. anim.ChangeType = (newHeight > previousHeight) ? HeightAnimation.ChangeTypes.Increased : HeightAnimation.ChangeTypes.Decreased;
  63. // Animate the Height from the txtHidden's previousHeight to its newHeight
  64. anim.From = previousHeight;
  65. anim.To = newHeight;
  66. // Start the animation
  67. anim.BeginAnimation();
  68. }
  69. /// <summary>
  70. /// Manages the AnimatedTextBox Height's animation.
  71. /// </summary>
  72. private class HeightAnimation
  73. {
  74. private Storyboard sb;
  75. private DoubleAnimation anim;
  76. private double _from;
  77. private double _to;
  78. private Duration _duration;
  79. private FrameworkElement _fe;
  80. private ChangeTypes _changeType;
  81. /// <summary>
  82. /// The possible types of the Height change.
  83. /// </summary>
  84. public enum ChangeTypes
  85. {
  86. Increased,
  87. Decreased
  88. }
  89. /// <summary>
  90. /// Constructor of the class.
  91. /// </summary>
  92. public HeightAnimation(FrameworkElement fe)
  93. {
  94. // Set the FrameworkElement which manages the animation
  95. _fe = fe;
  96. // Initialize the Storyboard
  97. sb = new Storyboard();
  98. sb.AutoReverse = false;
  99. // Initialize the animation
  100. anim = new DoubleAnimation();
  101. anim.Name = "anim";
  102. // Set the EasingFunction on a new instance of CubicEase whose EasingMode is EaseInOut
  103. anim.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseInOut };
  104. // Bind the Animation with the txtVisible TextBox
  105. Storyboard.SetTargetName(anim, "txtVisible");
  106. // Add the animation to the Storyboard's children
  107. sb.Children.Add(anim);
  108. }
  109. /// <summary>
  110. /// Gets or sets the type of the Height change.
  111. /// </summary>
  112. public ChangeTypes ChangeType
  113. {
  114. get { return _changeType; }
  115. set
  116. {
  117. _changeType = value;
  118. /* If the Height has inreased, set the target property to MaxHeight, else to MinHeight
  119. * (instead of animating directly the Height, we animate MaxHeight/MinHeight to prevent the AnimatedTextBox
  120. * from growing/shrinking suddenly) */
  121. Storyboard.SetTargetProperty(anim, new PropertyPath(string.Format("(TextBox.{0})", (value == ChangeTypes.Increased) ? "MaxHeight" : "MinHeight")));
  122. }
  123. }
  124. /// <summary>
  125. /// Gets or sets the animation's starting Height.
  126. /// </summary>
  127. public double From
  128. {
  129. get { return _from; }
  130. set
  131. {
  132. _from = value;
  133. anim.From = value;
  134. }
  135. }
  136. /// <summary>
  137. /// Gets or sets the animation's ending Height.
  138. /// </summary>
  139. public double To
  140. {
  141. get { return _to; }
  142. set
  143. {
  144. _to = value;
  145. anim.To = value;
  146. }
  147. }
  148. /// <summary>
  149. /// Gets or sets the animation's duration.
  150. /// </summary>
  151. public Duration Duration
  152. {
  153. get { return _duration; }
  154. set
  155. {
  156. _duration = value;
  157. anim.Duration = value;
  158. }
  159. }
  160. /// <summary>
  161. /// Begins the animation.
  162. /// </summary>
  163. public void BeginAnimation()
  164. {
  165. _fe.BeginStoryboard(sb);
  166. }
  167. }
  168. }

WPF中自动增加行(动画)的TextBox的更多相关文章

  1. JQuery实现表格自动增加行,对新行添加事件

    实现功能: 通常在编辑表格时表格的行数是不确定的,如果一次增加太多行可能导致页面内容太多,反应变慢:通过此程序实现表格动态增加行,一直保持最下面有多个空白行. 效果: 一:原始页面 二:表1增加新行并 ...

  2. WPF中的简单水动画

    原文 https://stuff.seans.com/2008/08/21/simple-water-animation-in-wpf/ 很多年前(80年代中期),我在一家拥有Silicon Grap ...

  3. wpf 中 Ellipse 对象对动画性能的影响

    vs2019 .NetFramework 4.8 win10-64 1909 接手一个wpf项目,某窗口中包含大量的 Shape 对象(线,矩形,圆形等). 这些内容要匀速的向左平移,类似于游戏&qu ...

  4. datagridview自动增加行高度和显示全部内容

    this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;  //自动调动dat ...

  5. 关于datagridview自动增加行高度和显示全部内容的设置

    this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;  //自动调动dat ...

  6. C# datagridview、datagrid、GridControl增加行号

    01 - WinForm中datagridview增加行号 在界面上拖一个控件dataGridView1,在datagridview添加行事件中添加如下代码: private void dataGri ...

  7. WPF中TextBox文件拖放问题

    在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同,具体可参考这篇文章Textbox ...

  8. 解决WPF中TextBox文件拖放问题

    在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同,具体可参考这篇文章Textbox ...

  9. 示例:WPF中自定义StoryBoarService在代码中封装StoryBoard、Animation用于简化动画编写

    原文:示例:WPF中自定义StoryBoarService在代码中封装StoryBoard.Animation用于简化动画编写 一.目的:通过对StoryBoard和Animation的封装来简化动画 ...

随机推荐

  1. 建立一个 Openshift "Do-It-Yourself" 应用

    建立一个 Openshift "Do-It-Yourself" 应用 Openshift 的  "Do-It-Yourself" 就是自己可以编译定制 WEB ...

  2. [D3] Animate Transitions in D3 v4

    D3 makes it easy to add meaningful animations to your data visualizations. Whether it’s fading in ne ...

  3. Undo表空间数据文件损坏

       UNDO表空间数据文件和system表空间数据文件都是数据库的关键数据文件,如果损坏会导致sql执行失败,用户无法登录,甚至实例崩溃等.同样恢复UNDO表空间数据文件也必须在数据库mount状态 ...

  4. SimpleDateFormat的使用问题

    今天对过去的代码进行重构,因为使用静态方法调用的原因,使用了一个静态的SimpleDateFormat,结果FindBug报错了,查看了一下,说是使用了静态的SimpleDateFormat对象. S ...

  5. 【CS Round #48 (Div. 2 only)】Game of Chance

    [链接]h在这里写链接 [题意] 在这里写题意 [题解] 在这里写题解 [错的次数] 0 [反思] 在这了写反思 [代码] #include <bits/stdc++.h> using n ...

  6. equals、HashCode与实体类的设计

    equals和HashCode都是用来去重的,即判断两个对象是否相等.如果是String类则我们直接用.equals()判断,如果是我们自己定义的类,需要有自己的判断方法,重写equals,如果是集合 ...

  7. Altium Designer如何移动选中的所有对象

    用shift去选中, 快捷键M S移动整体

  8. (转)Windows Server 2008 R2 域控制器部署指南

    转自:https://technet.microsoft.com/zh-cn/cloud/gg462955.aspx 一.域控制器安装步骤: 1.装 Windows Server 2008 R2并配置 ...

  9. Spring 使用Cache(转)

    从3.1开始Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事物管理的支持.Spring Cache是作用在方法上的,其核心思想是:当我们在调用一个缓存方法时会把该方法参数 ...

  10. 使用maven进行测试设置断点调试的方法

    在Maven中配置测试插件surefire来进行单元测试,默认情况下,surefire会执行文件名以Test开头或结尾的测试用例,或者是以TestCase结尾的测试用例.               ...