WPF中Grid容器内TextWrapping不生效问题求助
WPF ErrorTemplate中TextBlock宽度不随窗口调整的解决方案
问题描述
编写的WPF代码中,ErrorTemplate内的TextBlock未继承Grid的宽度,仅占用文本所需的最小宽度。需要实现TextBlock宽度随窗口大小动态调整,使文本自动换行。尝试将ErrorTemplate中的StackPanel替换为Grid后问题仍未解决。
相关代码
样式代码
<Style TargetType="PasswordBox" x:Key="passwordBoxStyle"> <Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <StackPanel > <!--the only thing that worked for me was set stackpanel witdh to 300--> <AdornedElementPlaceholder /> <TextBlock TextWrapping="Wrap" HorizontalAlignment="Stretch" Margin="0,5,5,0" Text="{Binding [0].ErrorContent}" Foreground="Red"></TextBlock> </StackPanel> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="Background" Value="#F5F7F9" /> <Setter Property="Foreground" Value="#767676" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderBrush" Value="#F5F7F9" /> <Setter Property="FontSize" Value="12" /> <Setter Property="Padding" Value="10 10" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="Margin" Value="0,10,10,10" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type PasswordBox}"> <Border x:Name="border" CornerRadius="3" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="True"> <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="BorderBrush" TargetName="border" Value="#d9d9d9"/> </Trigger> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="BorderBrush" Value="Red"></Setter> <Setter Property="Margin" Value="0,10,5,50" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
窗口代码
<Window x:Class="Vistas.prueba" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:w="clr-namespace:Vistas" Title="prueba" Height="300" Width="500"> <Grid Width="300" x:Name="gd" Background="Aqua"> <TextBlock Grid.Row="0" Text="Contrasena" /> <PasswordBox Name="txtContrasena" Grid.Row="1" Width="300" Style="{StaticResource passwordBoxStyle}" w:BoundPasswordBox.BoundPassword="{Binding Path=Usu_Contrasena, NotifyOnValidationError=True, ValidatesOnDataErrors=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> </Grid> </Window>
PasswordBox绑定辅助类代码
class BoundPasswordBox { private static bool _updating = false; public static readonly DependencyProperty BoundPasswordProperty = DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(BoundPasswordBox), new FrameworkPropertyMetadata(string.Empty, OnBoundPasswordChanged)); public static string GetBoundPassword(DependencyObject d) { return (string)d.GetValue(BoundPasswordProperty); } public static void SetBoundPassword(DependencyObject d, string value) { d.SetValue(BoundPasswordProperty, value); } private static void OnBoundPasswordChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) { PasswordBox password = d as PasswordBox; if (password != null) { // Disconnect the handler while we're updating. password.PasswordChanged -= PasswordChanged; } if (e.NewValue != null) { if (!_updating) { password.Password = e.NewValue.ToString(); } } else { password.Password = string.Empty; } // Now, reconnect the handler. password.PasswordChanged += new RoutedEventHandler(PasswordChanged); } static void PasswordChanged(object sender, RoutedEventArgs e) { PasswordBox password = sender as PasswordBox; _updating = true; SetBoundPassword(password, password.Password); _updating = false; } }
解决方案
问题核心在于ErrorTemplate所在的装饰层默认不受父容器宽度约束,需要显式将容器宽度绑定到AdornedElementPlaceholder对应的控件宽度。修改Validation.ErrorTemplate部分代码如下:
<Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <!-- 用Grid作为容器,并绑定宽度到AdornedElement的实际宽度 --> <Grid Width="{Binding ElementName=adornedPlaceholder, Path=ActualWidth}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- 给AdornedElementPlaceholder命名,用于绑定宽度 --> <AdornedElementPlaceholder x:Name="adornedPlaceholder" Grid.Row="0"/> <!-- TextBlock无需额外设置HorizontalAlignment,默认继承Grid宽度 --> <TextBlock Grid.Row="1" TextWrapping="Wrap" Margin="0,5,5,0" Text="{Binding [0].ErrorContent}" Foreground="Red"/> </Grid> </ControlTemplate> </Setter.Value> </Setter>
说明
AdornedElementPlaceholder代表被验证的PasswordBox,绑定它的ActualWidth可以让容器宽度和PasswordBox保持一致,随父Grid的宽度变化而动态调整。- 使用Grid并定义行布局,确保PasswordBox和错误提示文本垂直排列,同时TextBlock会自动继承Grid的宽度,实现文本自动换行。
内容的提问来源于stack exchange,提问作者maxc5
相关产品推荐
相关产品推荐

