我创建了一个类,它缩短文本以适应文本框,同时还添加“...”。
示例:
[ThisTextis]toolong > [ThisTex...]
我在Windows 8.1 VM(虚拟机)上使用Microsoft Visual Studio 2013,该软件是一个应用程序。
现在它可能并不完美,但这一切都很精彩。我现在想知道的是,如果我可以在该类之外创建一个布尔属性,那么用户可以在XAML中的文本框上启用/禁用它:
<TextBox CutText="True"/>
问题是我已经在类中使用了预先存在的Text
属性,而且我的代码并不像我希望的那样漂亮。
无论如何,我会很高兴得到任何建议和/或帮助。
编辑:简单地说,我想为TextBlock.TextTrimming
创建TextBox
属性,因为现有属性仅限于TextBlock
。
这是班级:
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);
}
}
}
答案 0 :(得分:4)
我很遗憾地通知你,你浪费了你的时间。 WPF已经内置了该功能。您可以将TextBlock.TextTrimming
property设置为CharacterEllipsis
或WordEllipsis
,这将自动修剪控件的溢出文本并添加省略号(...
)。看到这个简单的例子:
<TextBlock TextTrimming="CharacterEllipsis" Width="150">
Lorem ipsum dolor sit amet, consectetur adipisicing</TextBlock>
来自MSDN上的TextTrimming Enumeration页:
CharacterEllipsis
:文字在字符边界处被修剪。绘制省略号(...)代替剩余文本。
WordEllipsis
:文字在字边界处被修剪。绘制省略号(...)代替剩余文本。
更新&gt;&gt;&gt;
要更直接地回答您的问题,您应该在Attached Property中创建代码。这样,您可以定义bool
附加属性以使用省略号,例如。像这样的东西:
<TextBox TextBoxProperties.CutText="True" />
...其中TextBoxProperties
将是定义附加属性的类的名称,CutText
将是属性本身的名称。请参阅链接页面中的How to create an Attached Property section以了解如何执行此操作。您可以使用该属性中的CutText
类。
答案 1 :(得分:2)
使用其他答案中的建议,我编写了一个对您有用的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"/>
你可能不得不玩风格来获得理想的外观和感觉,但这个想法仍然存在。这是一个Control Template
,它扩展了TextBox
,可让您设置是否希望文本框修剪内容以及您需要修剪的类型。
有关Custom Controls
的详细信息,请参阅here。
答案 2 :(得分:0)
既不可能,也不必做你想做的事。您无法向现有组件添加新属性。另外,如果你check out this answer to another question,通过为TextBox
定义WPF样式,有一种更简单的方法来实现你想要做的事。