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

来源:互联网 发布:mac怎么把软件放桌面 编辑:程序博客网 时间:2024/06/08 17:40

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);        }    }}
0 0
原创粉丝点击