我想设置
WPF TextBox的宽度,以便它有足够的空间,例如,任何5位数的TCP端口号.它不应该更大,它不应该动态调整大小,即Width =“Auto”不是我想要的.
我正在寻找一种通用的方式,即尊重所用字体的方式,而且我不想在字体 – 或其他任何可能改变像素宽度的情况下使用像素精确的宽度值时摆弄它.数字 – 已更改.
我想有可能 – 如果笨拙 – 通过MeasureString在代码中做,但这在XAML中是否可行?
最佳答案 嗯,它可能不完美,但这是一个可能的解决方案.
创建一个ControlTemplate,它将包含所需的CharacterLength和GhostString依赖项属性.
public class DynamicTextBox : TextBox
{
public int CharacterLength
{
get { return (int)GetValue(CharacterLengthProperty); }
set { SetValue(CharacterLengthProperty, value); }
}
// Using a DependencyProperty as the backing store for CharacterLength. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CharacterLengthProperty =
DependencyProperty.Register("CharacterLength", typeof(int), typeof(DynamicTextBox), new PropertyMetadata(5, new PropertyChangedCallback(CharacterLengthChanged)));
public string GhostString
{
get { return (string)GetValue(GhostStringProperty); }
private set { SetValue(GhostStringProperty, value); }
}
// Using a DependencyProperty as the backing store for GhostString. This enables animation, styling, binding, etc...
public static readonly DependencyProperty GhostStringProperty =
DependencyProperty.Register("GhostString", typeof(string), typeof(DynamicTextBox), new PropertyMetadata("#####"));
static DynamicTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DynamicTextBox), new FrameworkPropertyMetadata(typeof(DynamicTextBox)));
}
private static void CharacterLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DynamicTextBox textbox = d as DynamicTextBox;
string ghost = string.Empty;
for (int i = 0; i < textbox.CharacterLength; i++)
ghost += "#";
textbox.GhostString = ghost;
}
}
每当CharacterLength属性发生更改时,都会重新计算GhostString属性,您将在一分钟内看到魔法.
为此新控件设置Style和ControlTemplate.
<Style TargetType="{x:Type local:DynamicTextBox}"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DynamicTextBox}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<TextBlock Text="{TemplateBinding GhostString}"
Visibility="Hidden"
Margin="3,0"/>
<ScrollViewer Margin="0"
x:Name="PART_ContentHost" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
GhostString属性放在Hidden TextBlock中,这意味着渲染宽度,但文本是不可见的,它仍然放在TextBox后面.
您可以像这样使用控件:
<Controls:DynamicTextBox CharacterLength="12" HorizontalAlignment="Left"/>
<Controls:DynamicTextBox CharacterLength="6" HorizontalAlignment="Left"/>
<Controls:DynamicTextBox CharacterLength="2" HorizontalAlignment="Left"/>
注意:我将HorizontalAlignment放在那里只是为了强制宽度折叠.
结果如下:
它并不完美,但它肯定是一个开始.如果你想进一步限制TextBox的宽度,我相当肯定你可以在ControlTemplate中做一些聪明的绑定.