我不确定为什么无法使用ScrollViewer解决方案。我需要一个具有固定初始宽度的TextBox来实现数字上下控件 - 在此控件中,TextBox独立于输入而收缩和扩展,如果UI随着您的键入而更改,则看起来非常烦人。
因此,我发现以下使用2个文本框的解决方案适合我。第一个文本框是显示给用户输入的文本框,第二个文本框通过依赖属性(DisplayLength)和下面显示的转换器进行初始化。
将第一个TextBox的MaxWidth属性绑定到第二个TextBox的Width属性可以修复大小,使用户可以键入所需内容,但即使有更多的UI空间可用,文本框的显示宽度也不会改变。
<TextBox x:Name="PART_TextBox"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value}"
Margin="0,0,1,0"
TextAlignment="Right"
AcceptsReturn="False"
SpellCheck.IsEnabled="False"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
MaxWidth="{Binding ElementName=TBMeasure, Path=ActualWidth}"
/>
<!-- Hidden measuring textbox ensures reservation of enough UI space
according to DisplayLength dependency property
-->
<TextBox x:Name="TBMeasure"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisplayLength, Converter={StaticResource ByteToPlaceHolderStringConverter}}"
Margin="0,0,1,0"
TextAlignment="Right"
AcceptsReturn="False"
SpellCheck.IsEnabled="False"
HorizontalContentAlignment="Right"
VerticalContentAlignment="Center"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Visibility="Hidden"/>
// Converter
[ValueConversion(typeof(byte), typeof(string))]
public sealed class ByteToPlaceHolderStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((value is byte) == false)
return Binding.DoNothing;
byte byteVal = (byte)value;
string retString = string.Empty;
for (int i = 0; i < byteVal; i++)
retString = retString + "X";
return retString;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}