WPF中自动增加行(动画)的TextBox
WPF中自动增加行(动画)的TextBox
WPF中的Textbox控件是可以自动换行的,只要设置TextWrapping属性为”Wrap”即可,但是存在一个问题:Textbox的高度是固定的,当输入文本过多时就会出现如下情况。
Textbox虽然没有自动增加高度的属性,但是我们可以通过设置来实现这一个功能。相关xaml代码如下
<Grid VerticalAlignment="Top" HorizontalAlignment="Left" Width="36" Height="100">
<TextBox x:Name="textBox" TextWrapping="Wrap" VerticalAlignment="Top" />
</Grid>
效果如下
这里需要注意的是
- 如果设置了textBox的Width、Height或者Margin属性,那么此textBox的大小就已经限制死了,不会自动增加,会出现上图中的情况。
- 如果想设置textBox的大小和位置,需要把textBox放在一个Grid中,通过Grid的属性来控制textBox(上文中xaml文件中的方法)
其实到此为止所需要的功能已经实现了,但是为了让让textbox更美观,我加了一个动画
效果如下:
表面上看是一个textbox,其实是一个Grid加上2个textBox(一个显示,一个隐藏),xaml代码如下
<Grid>
<TextBox x:Name="txtVisible" TextWrapping="Wrap"/>
<TextBox x:Name="txtHidden" TextWrapping="Wrap" Visibility="Hidden" VerticalAlignment="Top"/>
</Grid>
Grid是用来控制textbox的大小的,两个textbox中,显示的那个用于输入文字,隐藏的用于触发动画。原理如下
在txtVisible中输入文字的同时,txtVisible把text传递给txtHidden,当txtHidden中的内容已经满一行时,会触发SizeChange事件,这个事件再触发txtVisible高度变化动画。代码如下
public partial class txt : UserControl
{
private HeightAnimation anim;
private double _animationDuration;
public txt()
{
InitializeComponent();
// Initialize the animation
anim = new HeightAnimation(this);
AnimationDuration = 500; //default value
// Add the handlers to the required events
txtHidden.SizeChanged += TxtHidden_SizeChanged;
txtVisible.TextChanged += TxtVisible_TextChanged;
}
/// <summary>
/// Gets or sets a value indicating whether the control is animated on loaded.
/// </summary>
public bool AnimateOnLoaded { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether the control is animated.
/// </summary>
public bool IsAnimated { get; set; } = true;
/// <summary>
/// Gets or sets the duration of the animation.
/// </summary>
public double AnimationDuration
{
get { return _animationDuration; }
set
{
_animationDuration = value;
anim.Duration = new Duration(TimeSpan.FromMilliseconds(value));
}
}
/// <summary>
/// Gets or sets the text contents of the AnimatedTextBox.
/// </summary>
public string Text
{
get { return txtHidden.Text; }
set
{
txtHidden.Text = value;
txtVisible.Text = value;
}
}
private void TxtVisible_TextChanged(object sender, TextChangedEventArgs e)
{
// When the user's writing in txtVisible, we copy the text to txtHidden
txtHidden.Text = txtVisible.Text;
}
private void TxtHidden_SizeChanged(object sender, SizeChangedEventArgs e)
{
OnHeightChanged(e.PreviousSize.Height, e.NewSize.Height);
}
/// <summary>
/// To execute when the txtHidden's Height has changed.
/// </summary>
private void OnHeightChanged(double previousHeight, double newHeight)
{
//Animation type, increase txtVisible's height or decrease
anim.ChangeType = (newHeight > previousHeight) ? HeightAnimation.ChangeTypes.Increased : HeightAnimation.ChangeTypes.Decreased;
// Animate the Height from the txtHidden's previousHeight to its newHeight
anim.From = previousHeight;
anim.To = newHeight;
// Start the animation
anim.BeginAnimation();
}
/// <summary>
/// Manages the AnimatedTextBox Height's animation.
/// </summary>
private class HeightAnimation
{
private Storyboard sb;
private DoubleAnimation anim;
private double _from;
private double _to;
private Duration _duration;
private FrameworkElement _fe;
private ChangeTypes _changeType;
/// <summary>
/// The possible types of the Height change.
/// </summary>
public enum ChangeTypes
{
Increased,
Decreased
}
/// <summary>
/// Constructor of the class.
/// </summary>
public HeightAnimation(FrameworkElement fe)
{
// Set the FrameworkElement which manages the animation
_fe = fe;
// Initialize the Storyboard
sb = new Storyboard();
sb.AutoReverse = false;
// Initialize the animation
anim = new DoubleAnimation();
anim.Name = "anim";
// Set the EasingFunction on a new instance of CubicEase whose EasingMode is EaseInOut
anim.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseInOut };
// Bind the Animation with the txtVisible TextBox
Storyboard.SetTargetName(anim, "txtVisible");
// Add the animation to the Storyboard's children
sb.Children.Add(anim);
}
/// <summary>
/// Gets or sets the type of the Height change.
/// </summary>
public ChangeTypes ChangeType
{
get { return _changeType; }
set
{
_changeType = value;
/* If the Height has inreased, set the target property to MaxHeight, else to MinHeight
* (instead of animating directly the Height, we animate MaxHeight/MinHeight to prevent the AnimatedTextBox
* from growing/shrinking suddenly) */
Storyboard.SetTargetProperty(anim, new PropertyPath(string.Format("(TextBox.{0})", (value == ChangeTypes.Increased) ? "MaxHeight" : "MinHeight")));
}
}
/// <summary>
/// Gets or sets the animation's starting Height.
/// </summary>
public double From
{
get { return _from; }
set
{
_from = value;
anim.From = value;
}
}
/// <summary>
/// Gets or sets the animation's ending Height.
/// </summary>
public double To
{
get { return _to; }
set
{
_to = value;
anim.To = value;
}
}
/// <summary>
/// Gets or sets the animation's duration.
/// </summary>
public Duration Duration
{
get { return _duration; }
set
{
_duration = value;
anim.Duration = value;
}
}
/// <summary>
/// Begins the animation.
/// </summary>
public void BeginAnimation()
{
_fe.BeginStoryboard(sb);
}
}
}
WPF中自动增加行(动画)的TextBox的更多相关文章
- JQuery实现表格自动增加行,对新行添加事件
实现功能: 通常在编辑表格时表格的行数是不确定的,如果一次增加太多行可能导致页面内容太多,反应变慢:通过此程序实现表格动态增加行,一直保持最下面有多个空白行. 效果: 一:原始页面 二:表1增加新行并 ...
- WPF中的简单水动画
原文 https://stuff.seans.com/2008/08/21/simple-water-animation-in-wpf/ 很多年前(80年代中期),我在一家拥有Silicon Grap ...
- wpf 中 Ellipse 对象对动画性能的影响
vs2019 .NetFramework 4.8 win10-64 1909 接手一个wpf项目,某窗口中包含大量的 Shape 对象(线,矩形,圆形等). 这些内容要匀速的向左平移,类似于游戏&qu ...
- datagridview自动增加行高度和显示全部内容
this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders; //自动调动dat ...
- 关于datagridview自动增加行高度和显示全部内容的设置
this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders; //自动调动dat ...
- C# datagridview、datagrid、GridControl增加行号
01 - WinForm中datagridview增加行号 在界面上拖一个控件dataGridView1,在datagridview添加行事件中添加如下代码: private void dataGri ...
- WPF中TextBox文件拖放问题
在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同,具体可参考这篇文章Textbox ...
- 解决WPF中TextBox文件拖放问题
在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同,具体可参考这篇文章Textbox ...
- 示例:WPF中自定义StoryBoarService在代码中封装StoryBoard、Animation用于简化动画编写
原文:示例:WPF中自定义StoryBoarService在代码中封装StoryBoard.Animation用于简化动画编写 一.目的:通过对StoryBoard和Animation的封装来简化动画 ...
随机推荐
- jquery中$(dom).each()和$(dom).length的使用
1.$(dom).each();在dom处理上用的比较多. $(selector).each(function(index,element){ //selector会遍历当前页面里所有匹配的jquer ...
- h5做app和原生app有什么区别?
h5做app和原生app有什么区别? 一.总结 一句话总结: 二.h5做app和原生app有什么区别? 普通的HTML5技术与原生技术相比,有跨平台.动态.开放.直达二级内容页面等特点,但却在性能.工 ...
- 2.JPA学习总结
转自:https://shmilyaw-hotmail-com.iteye.com/blog/1969190 前言 最近在做一个项目的时候因为牵涉到要对数据库的操作,在最开始实现的时候采用了直接的JD ...
- 软件——python,主函数
1;; 如何在spyder中运行python程序 如下图, 写入一个输出 ' hellow word '的程序 然后点击运行按钮就可以运行了.
- Fiddler抓包工具详细介绍
本文转自:http://www.cnblogs.com/Chilam007/p/6985379.html 一.Fiddler与其他抓包工具的区别 1.Firebug虽然可以抓包,但是对于分析http请 ...
- JavaScript字符串替换replace方法
在日常的js开发中, 当要把字符串中的内容替换时,如果使用类似C#的string.replace方法,如下 var str='aabbccaa'; str=str.replace('aa','dd') ...
- [Angular] New async 'as' syntax and ngIf.. else
From Anuglar v4 above, we are able to using 'as' with async pipe. This allow as using 'new variable' ...
- php中嵌套html代码和html代码中嵌套php方式
php中嵌套html代码和html代码中嵌套php方式 一.总结 拷贝的话直接html代码是极好的方式 1.php中嵌套html代码(本质是原生php):a.原生嵌套<?php .....?&g ...
- php 获取隔日日期
php获取日期时间 <?php date_default_timezone_set('PRC'); //默认时区 echo "今天:",date("Y-m-d&qu ...
- Java学习很好的笔记
http://www.cnblogs.com/vamei/archive/2013/03/31/2991531.html