原文: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. fromCharCode vs chr

    fromCharCode vs chr echo off set "fn=%*" set php=d:/www/php5/php.exe cls echo. %php% %fn% ...

  2. Android RecyclerView嵌套RecyclerView

    原理 RecyclerView嵌套RecyclerView的条目,项目中可能会经常有这样的需求,但是我们将子条目设置为RecyclerView之后,却显示不出来.自己试了很久,终于找到了原因:必须先设 ...

  3. controller接收参数的对象是vo还是dto?

    我也没有深入了解过,就我使用情况来说的话,VO和DTO在实际开发过程中其实可以是一样的.从定义上来说他们区别于使用的所在层,VO(view object)视图对象,DTO(Data Transfer  ...

  4. The Swift Programming Language 中文翻译版

    原文(http://www.cnblogs.com/lkvt/p/3765349.html) 一.Welcome to Swift 1.关于Swift Swift是一种用于iOS和OS X应用的全新编 ...

  5. js进阶 14-3 如何接收load函数从后台接收到的返回数据

    js进阶 14-3 如何接收load函数从后台接收到的返回数据 一.总结 一句话总结:load方法的回调函数的参数即可接收从后台的返回数据. 1.load方法的回调函数的参数是什么? 语法:load( ...

  6. Java 学习(18):Java 序列化& 网络编程& 发送邮件

    --Java 序列化 -- 网络编程 -- 发送邮件 Java 序列化 Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据.有关对象的类型的信 ...

  7. 仿招商银行载入loading效果

    在招商银行android手机app中.有例如以下图所看到的的loading载入效果: 实现这个效果还是比較简单,就是自己定义dialog,设置自己想要的布局.然后设置旋转动画. 主要步骤: 1,写布局 ...

  8. LA 3887 - Slim Span 枚举+MST

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  9. Textillate.js有什么用及使用实例

    Textillate.js有什么用及使用实例 一.总结 一句话总结:Textillate.js – 实现动感的 CSS3 文本动画的简单插件 二.textillate.js 文字动画 textilla ...

  10. 嵌入式arm linux环境中gdb+gdbserver调试

    一.前言嵌入式Linux系统中,应用开发过程中,很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程序.采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,通常采 ...