从类中创建属性

本文关键字:属性 创建 | 更新日期: 2023-09-27 17:54:44

我创建了一个类,它缩短了文本以适合文本框,同时还添加了"…"。

的例子:

[ThisTextis]toolong > [ThisTex...]

我在Windows 8.1 VM(虚拟机)上使用Microsoft Visual Studio 2013,该软件是一个应用程序。

现在它可能不是完美的,但这一切都很好。现在我想知道的是,我是否可以从这个类中创建一个布尔属性,这样用户就可以在XAML:

的文本框中启用/禁用它
<TextBox CutText="True"/>

问题是我已经在类中使用了预先存在的Text属性,并且我的代码不像我希望的那样漂亮。无论如何,我将非常高兴得到任何建议和/或帮助。

编辑:简单地说,我想为TextBox创建TextBlock.TextTrimming属性,因为已经存在的属性仅限于TextBlock

下面是Class:

 class CutText
    {
        //Create a new instance of a textbox
        TextBox textCut = new TextBox();
        //Reset at start
        public void ResetText(TextBox text)
        {
            //Overwrite textCut with the chosen TextBox
            textCut = text;
            //Handles the possibility of already filled textbox
            if (textCut.Text != "" || textCut.Text != null)
            {
                _text = textCut.Text;
            }
            //Prevents text from being 'Null' 
            else
            {
                _text = "";
            }
        }
        //Cuts text to width of textbox
        private string CutTextToWidth(string text, double fontSize, double width)
        {
            //boolean to check if width of text is correct
            bool validArea = false;
            //comply with difference in width of characters 
            double CharDiffLength = (stringWidth("M", fontSize) - stringWidth("|", fontSize));
            //shortened text
            string shortText = text;
            //last length which was too long
            int LastLongLen = text.Length;
            //last length which fit into textbox
            int LastFitLen = 0; 
            if (stringWidth(text, fontSize) < width)
            {
                shortText = text;
            }
            else
            {
                //repeat until the text fits into the appointed area
                while (!validArea)
                {
                    if (width < stringWidth(shortText, fontSize))
                    {
                        //text is still too long
                        LastLongLen = shortText.Length;
                    }
                    else
                    {
                        //text is not too long
                        LastFitLen = shortText.Length;
                    }
                    int newLen = (LastFitLen + LastLongLen) / 2;
                    if (shortText.Length != newLen)
                    {
                        //set shortened text
                        shortText = text.Substring(0, newLen) + "'u2026";
                    }
                    validArea = ((width - 10 < stringWidth(shortText, fontSize)) && (stringWidth(shortText, fontSize) < width));
                }
            }
            //return the shortened text
            return shortText;
        }
        //Calculate the width of the text
        private double stringWidth(string s, double fontSize)
        {
            if (s == " ")
                s = "'u00a0";
            TextBlock t = new TextBlock()
            {
                FontSize = fontSize,
                Text = s
            };
            t.Measure(new Size(double.MaxValue, double.MaxValue));
            return t.ActualWidth;
        }
        //(GotFocus) Replaces cut text with full text and places the cursor at the chosen position
        public void GotFocusText()
        {
            int index = textCut.SelectionStart;
            textCut.Text = _text;
            textCut.SelectionStart = index;
        }
        //(LostFocus) Saves cut text into property / empties the textbox if nothing has been written and sets tooltip
        public void LostFocusText()
        {
            if (!string.IsNullOrWhiteSpace(textCut.Text))
            {
                Text = textCut.Text;
            }
            else
            {
                Text = "";
            }
            ToolTipService.SetToolTip(textCut, _text);
        }
        //TextBox.Text Property
        private string _text;
        public string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                //Receive text, fontsize and width of textbox
                textCut.Text = CutTextToWidth(_text, textCut.FontSize, textCut.Width - 25);
            }
        }
    }

从类中创建属性

我很抱歉地告诉你,你浪费了你的时间。WPF已经内置了这个功能。您可以将TextBlock.TextTrimming属性设置为CharacterEllipsisWordEllipsis,这将自动修剪控件的溢出文本并添加省略号(...)。请看这个简单的例子:

<TextBlock TextTrimming="CharacterEllipsis" Width="150">
    Lorem ipsum dolor sit amet, consectetur adipisicing</TextBlock>

来自MSDN上的texttrim Enumeration页面:

CharacterEllipsis:文本在字符边界处被修剪。用省略号(…)代替剩余的文本。

WordEllipsis:文本在单词边界处被修剪。用省略号(…)代替剩余的文本。


,

更新祝辞祝辞的在

要更直接地回答您的问题,您应该在附加属性中创建代码。这样,您就可以定义bool附加属性来使用省略号,例如:像这样:

<TextBox TextBoxProperties.CutText="True" />

…其中TextBoxProperties是定义附加属性的类的名称,CutText是属性本身的名称。请参阅如何从链接页创建附加属性一节,了解如何创建附加属性。您可以使用该属性中的CutText

根据其他回答的建议,我编写了一个Custom Control,应该对你有用。

public class TrimmedTextBox : TextBox
{
    public bool Trim
    {
        get { return (bool)GetValue(TrimProperty); }
        set { SetValue(TrimProperty, value); }
    }
    // Using a DependencyProperty as the backing store for Trim.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TrimProperty =
        DependencyProperty.Register("Trim", typeof(bool), typeof(TrimmedTextBox), new PropertyMetadata(true));
    public TextTrimming Trimming
    {
        get { return (TextTrimming)GetValue(TrimmingProperty); }
        set { SetValue(TrimmingProperty, value); }
    }
    // Using a DependencyProperty as the backing store for Trimming.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TrimmingProperty =
        DependencyProperty.Register("Trimming", typeof(TextTrimming), typeof(TrimmedTextBox), new PropertyMetadata(TextTrimming.CharacterEllipsis));
    static TrimmedTextBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(TrimmedTextBox), new FrameworkPropertyMetadata(typeof(TrimmedTextBox)));
    }
}

Style:

<Style TargetType="{x:Type local:TrimmedTextBox}"
       BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TrimmedTextBox}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <ScrollViewer x:Name="PART_ContentHost"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsKeyboardFocused" Value="False"/>
                <Condition Property="Trim" Value="True"/>
            </MultiTrigger.Conditions>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                            <TextBlock Text="{TemplateBinding Text}" 
                                       TextTrimming="{Binding Trimming, RelativeSource={RelativeSource TemplatedParent}}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </MultiTrigger>
    </Style.Triggers>
</Style>

用法:

<local:TrimmedTextBox Trim="True" 
                      Text="Le toucan has arrived" 
                      Width="50" 
                      Trimming="CharacterEllipsis"/>

您可能需要使用样式来获得所需的外观和感觉,但想法仍然存在。这是一个扩展了TextBoxControl Template,它将允许你设置你是否想要文本框修剪内容,以及你需要什么类型的修剪。

有关Custom Controls的更多信息,请参阅此处

做你想做的事既不可能,也没有必要。您不能像那样向现有组件添加新属性。此外,如果您查看了对另一个问题的答案,那么通过为TextBox定义WPF样式,有一种更简单的方法可以实现您想要做的事情。