原文: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的更多相关文章

  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. 文字记录而已!!人民币直充/兑换PayPal美金

    人民币直充/兑换PayPal美金 用PAYPAL国际使用外国货币,没有信用卡是不能冲值的,到淘宝买吧,被骗的几率大一些,弄来弄去,PAYPAL被冻结. 今天朋友介绍使用 中美互动网 让它给自己的PAY ...

  2. Android 技巧 - Debug 判断不再用 BuildConfig

    Android 开发中一般会通过 BuildConfig.DEBUG 判断是否是 Debug 模式,从而做一些在 Debug 模式才开启的特殊操作,比如打印日志.这样好处是不用在发布前去主动修改,因为 ...

  3. 【Educational Codeforces Round 33 D】Credit Card

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每次遇到0的时候,看看当前累计的delta是多少. 如果大于0,则temp = d-delta; 小于0,取temp2 = min( ...

  4. [D3] Debug D3 v4 with Dev Tools

    Since D3 outputs standard markup, you can use familiar dev tools and inspectors to debug your visual ...

  5. 并发,two

    引言 为了更加形象的描述并发的基础知识,因此本文LZ采用了园子里一度大火的标题形式--"没听说过XXXX,就不要说你XXXX了".希望能够给猿友们一个醒目的警醒,借此来普及并发的基 ...

  6. 互信息 & 卡方 - 文本挖掘

    在做文本挖掘,特别是有监督的学习时,常常需要从文本中提取特征,提取出对学习有价值的分类,而不是把所有的词都用上,因此一些词对分类的作用不大,比如“的.是.在.了”等停用词.这里介绍两种常用的特征选择方 ...

  7. 10.14 android输入系统_多点触摸驱动测试及Reader线程、InputStage分析

    21. 多点触摸_电容屏驱动程序_实践_tiny4412 tiny4412触摸屏: 分辨率为800 x 480http://wiki.friendlyarm.com/wiki/index.php/LC ...

  8. 【Codeforces Round #185 (Div. 2) D】Cats Transport

    [链接] 链接 [题意] 有n座山,m只猫. 每只猫都在其中的一些山上玩. 第i只猫在h[i]山上玩,且会在t[i]时刻出现在山脚下(然后就一直在那里等) 然后有p个人. 它们听从你的安排. 在某个时 ...

  9. 计算机图形学(二)输出图元_3_画线算法_2_DDA算法

    DDA算法        数字微分分析仪(digital differential analyzer, DDA)方法是一种线段扫描转换算法.基于使用等式(3.4)或等式(3.5)计算的&x或& ...

  10. 数据库中substring的用法 CONVERT(varchar(12) , getdate(), 112 )

    Sqlserver中常常要操作一些时间类型的字段转换,我又不太记得住,所以搜集了下面的一些SqlserverConvertDateTime相关的资料发表在自己的小站里,方便自己以后要用的时候寻找,望对 ...