Можно ли масштабировать размер текста внутри текстового поля, когда текст начинает выходить за границы?

Так что вопрос довольно прост. Возможно ли это в Silverlight 4?

Обновление:

Это код, который я получил при попытке обновить решение edventuro.us для текстового блока

namespace EmpresaHR.Controls
{
    using System.Windows;
    using System.Windows.Controls;

    /// <summary>
    /// A simple text control that shrinks or expands the font of the text to
    /// display all of the text in the preferred size of the textblock.
    /// Dependency Properties:
    /// - MinFontSize: This is the smallest size the font will be reduced to. Defaults to 8pt.
    /// - MaxFontSize: This is the largest size the font will be increased to. Defaults to 20.
    /// - ScalingMode: This controls if the font size should be scaled only up, or down, or both ways
    /// to fit the text within the boundaries of the textbox.  Defaults to BothWays.
    /// - StepSize:    This is the point size the font will be increased or decreased 
    /// by each iteration until the text fits the desired size. Higher amounts will require fewer iterations,
    /// so will be faster, but the changes will be more abrupt. Defaults to 0.5.
    /// </summary>
    public class AutoScalingTextBox : ContentControl
    {
        #region Text (DependencyProperty)

        /// <summary>
        /// Gets or sets the Text DependencyProperty. This is the text that will be displayed.
        /// </summary>
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(AutoScalingTextBox),
            new PropertyMetadata(null, new PropertyChangedCallback(OnTextChanged)));

        private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((AutoScalingTextBox)d).OnTextChanged(e);
        }

        protected virtual void OnTextChanged(DependencyPropertyChangedEventArgs e)
        {
            this.InvalidateMeasure();
        }

        #endregion

        #region MinFontSize (DependencyProperty)

        private double _minFontSize = 8d;

        /// <summary>
        /// Gets or sets the MinFontSize property. This is the smallest size the font will be reduced to. Defaults to 8pt.
        /// </summary>
        public double MinFontSize
        {
            get { return (double)GetValue(MinFontSizeProperty); }
            set { SetValue(MinFontSizeProperty, value); }
        }
        public static readonly DependencyProperty MinFontSizeProperty =
            DependencyProperty.Register("MinFontSize", typeof(double), typeof(AutoScalingTextBox),
            new PropertyMetadata(8d, new PropertyChangedCallback(OnMinFontSizeChanged)));

        private static void OnMinFontSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((AutoScalingTextBox)d).OnMinFontSizeChanged(e);
        }

        protected virtual void OnMinFontSizeChanged(DependencyPropertyChangedEventArgs e)
        {
            _minFontSize = (double)e.NewValue;
            this.InvalidateMeasure();
        }

        #endregion

        #region MaxFontSize (DependencyProperty)

        private double _maxFontSize = 20d;

        /// <summary>
        /// Gets or sets the MaxFontSize property. This is the largest size the font will be increased to. Defaults to 20.
        /// </summary>
        public double MaxFontSize
        {
            get { return (double)GetValue(MaxFontSizeProperty); }
            set { SetValue(MaxFontSizeProperty, value); }
        }
        public static readonly DependencyProperty MaxFontSizeProperty =
            DependencyProperty.Register("MaxFontSize", typeof(double), typeof(AutoScalingTextBox),
            new PropertyMetadata(20d, new PropertyChangedCallback(OnMaxFontSizeChanged)));

        private static void OnMaxFontSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((AutoScalingTextBox)d).OnMaxFontSizeChanged(e);
        }

        protected virtual void OnMaxFontSizeChanged(DependencyPropertyChangedEventArgs e)
        {
            _maxFontSize = (double)e.NewValue;
            this.InvalidateMeasure();
        }

        #endregion

        #region ScalingMode (DependencyProperty)

        public enum ScalingModeOptions { BothWays, UpOnly, DownOnly };

        private ScalingModeOptions _scalingMode = ScalingModeOptions.BothWays;

        /// <summary>
        /// Gets or sets the ScalingMode property. This controls if the font size should be scaled only up, or down, or both ways
        /// to fit the text within the boundaries of the textbox.  Defaults to BothWays.
        /// </summary>
        public ScalingModeOptions ScalingMode
        {
            get { return (ScalingModeOptions)GetValue(ScalingModeProperty); }
            set { SetValue(ScalingModeProperty, value); }
        }
        public static readonly DependencyProperty ScalingModeProperty =
            DependencyProperty.Register("ScalingMode", typeof(ScalingModeOptions), typeof(AutoScalingTextBox),
            new PropertyMetadata(ScalingModeOptions.BothWays, new PropertyChangedCallback(OnScalingModeChanged)));

        private static void OnScalingModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((AutoScalingTextBox)d).OnScalingModeChanged(e);
        }

        protected virtual void OnScalingModeChanged(DependencyPropertyChangedEventArgs e)
        {
            // _scalingMode = (ScalingModeOptions) Enum.Parse(typeof(ScalingModeOptions), (string) e.NewValue, true);
            _scalingMode = (ScalingModeOptions)e.NewValue;
            this.InvalidateMeasure();
        }

        #endregion

        #region StepSize (DependencyProperty)

        private double _stepSize = 0.5d;

        /// <summary>
        /// Gets or sets the StepSize property. This is the point size the font will be increased or decreased 
        /// by each iteration until the text fits the desired size. Higher amounts will require fewer iterations,
        /// so will be faster, but the changes will be more abrupt. Defaults to 0.5.
        /// </summary>
        public double StepSize
        {
            get { return (double)GetValue(StepSizeProperty); }
            set { SetValue(StepSizeProperty, value); }
        }
        public static readonly DependencyProperty StepSizeProperty =
            DependencyProperty.Register("StepSize", typeof(double), typeof(AutoScalingTextBox),
            new PropertyMetadata(0.5d, new PropertyChangedCallback(OnStepSizeChanged)));

        private static void OnStepSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((AutoScalingTextBox)d).OnStepSizeChanged(e);
        }

        protected virtual void OnStepSizeChanged(DependencyPropertyChangedEventArgs e)
        {
            _stepSize = (double)e.NewValue;
            this.InvalidateMeasure();
        }

        #endregion

        /// <summary>
        /// A TextBlock that is set as the control's content and is ultimately the control 
        /// that displays our text
        /// </summary>
        private readonly TextBox textBox;

        /// <summary>
        /// Initializes a new instance of the DynamicTextBlock class
        /// </summary>
        public AutoScalingTextBox()
        {
            // Create our TextBlock and initialize
            this.textBox = new TextBox();
            this.Content = this.textBox;

            // Force TextWrapping on
            this.textBox.TextWrapping = TextWrapping.Wrap;
        }

        /// <summary>
        /// Handles the measure part of the measure and arrange layout process. During this process
        /// we measure the textBox that we've created as content with increasingly bigger/smaller font sizes
        /// until we find the font size that fits.
        /// </summary>
        /// <param name="availableSize">The available size</param>
        /// <returns>The base implementation of Measure</returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            Size unboundSize = new Size(availableSize.Width, double.PositiveInfinity);

            // Set the text and measure it to see if it fits without alteration
            this.textBox.Text = this.Text??"";
            Size textSize = base.MeasureOverride(unboundSize);

            // Scale up first if necessary
            while (textSize.Height < availableSize.Height)
            {
                // Increase the font size
                this.textBox.FontSize = this.textBox.FontSize + _stepSize;
                textSize = base.MeasureOverride(unboundSize);

                if (_scalingMode == ScalingModeOptions.DownOnly)
                {
                    if (this.textBox.FontSize > this.FontSize)
                    {
                        this.textBox.FontSize = this.FontSize;
                        break;
                    }
                }

                if (this.textBox.FontSize >= _maxFontSize)
                {
                    this.textBox.FontSize = _maxFontSize;
                    break;
                }
            }

            // Then scale down if neccessary
            while (textSize.Height > availableSize.Height)
            {
                // Reduce the font size
                this.textBox.FontSize = this.textBox.FontSize - _stepSize;
                textSize = base.MeasureOverride(unboundSize);

                if (_scalingMode == ScalingModeOptions.UpOnly)
                {
                    if (this.textBox.FontSize < this.FontSize)
                    {
                        this.textBox.FontSize = this.FontSize;
                        break;
                    }
                }

                if (this.textBox.FontSize <= _minFontSize)
                {
                    this.textBox.FontSize = _minFontSize;
                    break;
                }

            }

            return base.MeasureOverride(availableSize);
        }

    }
}

Во-первых, я не могу редактировать текст внутри текстового поля, когда он получен через привязку Во-вторых, я не уверен, как правильно масштабировать TextBox внутри ContentControl

5
задан v00d00 15 July 2011 в 11:29
поделиться