【问题标题】:Textbox will not stretch to fill viewbox文本框不会拉伸以填充视图框
【发布时间】:2012-01-04 11:40:24
【问题描述】:

我希望 LOB 表单中的标签和文本框的字体大小随着窗口大小或分辨率的变化而增大和缩小。为了实现这一点,我将标签和文本框放在了视图框内。

标签和自定义单选按钮的行为符合我的预期,但文本框不会水平拉伸以填充视图框(抱歉,由于代表无法发布图像)。如果您输入文本框,文本框将水平填充视图框。

这是我正在使用的代码示例:

  <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.186*"/>
            <ColumnDefinition Width="0.814*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="0.127*"/>
            <RowDefinition Height="0.873*"/>
        </Grid.RowDefinitions>
        <Viewbox Margin="0,0,0.917,0">
            <Label Content="First name:"/>
        </Viewbox>
        <Viewbox Grid.Column="1">
            <TextBox TextWrapping="Wrap"/>
        </Viewbox>
    </Grid>

我尝试在视图框中放置网格、堆栈面板和停靠面板(LastChildFill="True"),然后将文本框放置在这些布局控件中,但这也不起作用。反正有没有让文本框水平填充父视图框?

此问题与此类似:WPF TextBox won't fill in StackPanel 但此问题与堆栈面板有关,而不是视图框。

【问题讨论】:

  • 第一件事是使您的 xaml 正确:您没有为每个网格项目指定列/行。
  • @VincentPiel 这实际上并不重要。列和行默认为 0。

标签: wpf forms layout textbox viewbox


【解决方案1】:

只需使用转换器

像这样设置 FontSize: FontSize="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight ,Converter={StaticResource heightconverter}, ConverterParameter=3}"

public class ProcentualHeightConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (parameter is string p)
        {
            if (value is double v)
            {
                var result = double.TryParse(p, out double param);
                if (result)
                {
                    return v / param;
                }
            }
        } 
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

【讨论】:

    【解决方案2】:

    如果你想要的东西不起作用/不容易,那就假装它:

        <TextBox GotFocus="TextBox_GotFocus" HorizontalAlignment="Stretch" BorderThickness="0" Grid.Column="1"/>
        <Viewbox HorizontalAlignment="Left" Stretch="Uniform" Grid.Column="1">
            <TextBox x:Name="NameTextBox" Width="50" TextWrapping="Wrap" Text="Text" BorderThickness="0"/>
        </Viewbox>
    
        private void TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            NameTextBox.Focus();
            NameTextBox.SelectionStart = NameTextBox.Text.Length;
        }
    

    基本上发生的情况是另一个TextBoxViewbox 后面,当后面的TextBox 获得焦点时,它会将焦点切换到ViewboxTextBox。这将产生一些奇怪的调整大小,因为您的网格设置具有相对大小。您需要调整网格列/宽度的大小,直到获得所需的效果。

    【讨论】:

    • 由于上述dowhilefor答案的缺陷,我更喜欢这个 - 另外这个更简单! (但很遗憾,WPF 在这里失败了……)
    【解决方案3】:

    我认为你想要的并不容易。 ViewBox 在布局的测量过程中告诉它的孩子他们有无限的空间。之后,显示适合视图框。现在一个文本框,被告知有无限的空间,显然不能伸展。 我有 2 个解决方案,我认为这不是您想要的,但无论如何可能会有所帮助。

    第一个:

    <Viewbox Grid.Column="1" Grid.Row="0" Stretch="Uniform" >
        <Grid Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Viewbox}}, Path=ActualWidth}">
          <TextBox TextWrapping="Wrap" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
        </Grid>
    </Viewbox>
    

    这实际上会拉伸您的文本框,但会禁用视图框的预期行为。为什么?我们告诉 ViewBox 保持纵横比,并将文本框设置为填充整个视图框的宽度,从而保持文本框的大小。

    第二个:

    将向网格添加一个高度,取自标签,并使用其视图框的 scaletransform 进行修改。

    这个我没试过,但它会涉及一个值转换器。

    结论:没有简单的方法可以实现您想要的,因为视图框布局其子项的方式。如果您只想水平拉伸,如果您想缩放,我的第一个解决方案可以正常工作。我的猜测是你必须自己做。

    【讨论】:

    • 关于绑定到 AcutalWidth 或 ActualHeight 的警告:“由于 ActualHeight 是一个计算值,您应该知道,由于布局系统。布局系统可能正在计算子元素所需的度量空间、父元素的约束等。这可能会导致对 ActualHeight 或 ActualWidth 的任何绑定在每次调整大小时触发多次。如果这些绑定太多,这将对性能产生影响。
    • +1 当然你是对的,值得指出,但在这种情况下,我不知道更好的解决方案。
    • 哈哈!我没有实际宽度就做到了!
    • 感谢您的回答。你是对的,第一个选项确实打破了视图框,我认为这个问题没有一个简单的答案。我想一旦我了解了有关 WPF 的更多信息,我可能会稍后再讨论它。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    相关资源
    最近更新 更多