C# 触发IDataErrorInfo时无法调整StackPanel的大小

C# 触发IDataErrorInfo时无法调整StackPanel的大小,c#,wpf,xaml,C#,Wpf,Xaml,当TextBox元素出现错误时,自定义装饰器不会调整TextBox控件所在的StackPanel的大小: 使用DockPanel.Bottom会导致装饰器在下面的文本框上重叠。 我不知羞耻地说出的代码: 但是我不能重用数据模板 我的问题类似于: 我只是想要一个不同的解决方案 有什么想法吗?谢谢装饰器层与WPF中的主渲染层分开放置。将装饰器简单地看作一个图形覆盖层,它包含控件的形状它的元素标记环绕(例如类似于边框的行为) 对于每个控件,您不需要单独的装饰器。这意味着理想的解决方案是在尽可能高的级

当TextBox元素出现错误时,自定义装饰器不会调整TextBox控件所在的StackPanel的大小:

使用DockPanel.Bottom会导致装饰器在下面的文本框上重叠。 我不知羞耻地说出的代码:

但是我不能重用数据模板

我的问题类似于:

我只是想要一个不同的解决方案


有什么想法吗?谢谢

装饰器
层与WPF中的主渲染层分开放置。将
装饰器
简单地看作一个图形覆盖层,它包含
控件的形状
它的元素标记环绕(例如类似于
边框
的行为)


对于每个
控件
,您不需要单独的
装饰器
。这意味着理想的解决方案是在尽可能高的级别上添加
装饰器
,例如您的
窗口
,以便始终保证您拥有
装饰器
范围。

装饰器
层与WPF中的主渲染层分开。将
装饰器
简单地看作一个图形覆盖层,它包含
控件的形状
它的元素标记环绕(例如类似于
边框
的行为)


对于每个
控件
,您不需要单独的
装饰器
。这意味着理想的解决方案是在尽可能高的级别上添加
装饰器
,例如您的
窗口
,这样您就可以始终得到
装饰器
范围的保证。

我简直不敢相信!我自己想出来的:D

<UserControl.Resources>
        <Style x:Key="textblockErrorTooltip" TargetType="TextBlock">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="Margin" Value="10 0 10 0" />
        </Style>

        <DataTemplate x:Key="errortemplate">
            <Border Height="Auto" Margin="5,0,0,0" Background="#DC000C" CornerRadius="3" DockPanel.Dock="Right">
                <TextBlock  Style="{StaticResource textblockErrorTooltip}" Text="{Binding Path=(Validation.Errors)[0].ErrorContent}"></TextBlock>
            </Border>
        </DataTemplate>

        <Style x:Key="ContentControlErrorTemplate" TargetType="ContentControl">
            <Setter Property="ContentTemplate" Value="{x:Null}"/>

            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}, Path=Children[1].(Validation.HasError)}"  Value="True">
                    <Setter Property="ContentTemplate" >
                        <Setter.Value>
                            <DataTemplate>
                                <Border Height="Auto" Margin="5,0,0,0" Background="#DC000C" CornerRadius="3" DockPanel.Dock="Right">
                                    <TextBlock  Style="{StaticResource textblockErrorTooltip}" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}, Path=Children[1].(Validation.Errors)[0].ErrorContent}"></TextBlock>
                                </Border>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
</UserControl.Resources>

  <StackPanel Orientation="Horizontal" Grid.Row="4">
    <Label  Padding="0,0,20,0">Name:</Label>
    <TextBox  Padding="0,0,10,0" Width="150" x:Name="name" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"></TextBox>
    <ContentControl Style="{StaticResource ContentControlErrorTemplate}">
    </ContentControl>
  </StackPanel>

姓名:

如果你有改进的想法,请告诉我。我不确定它的效率有多高,但它确实有效。

我简直不敢相信!我自己想出来的:D

<UserControl.Resources>
        <Style x:Key="textblockErrorTooltip" TargetType="TextBlock">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="Margin" Value="10 0 10 0" />
        </Style>

        <DataTemplate x:Key="errortemplate">
            <Border Height="Auto" Margin="5,0,0,0" Background="#DC000C" CornerRadius="3" DockPanel.Dock="Right">
                <TextBlock  Style="{StaticResource textblockErrorTooltip}" Text="{Binding Path=(Validation.Errors)[0].ErrorContent}"></TextBlock>
            </Border>
        </DataTemplate>

        <Style x:Key="ContentControlErrorTemplate" TargetType="ContentControl">
            <Setter Property="ContentTemplate" Value="{x:Null}"/>

            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}, Path=Children[1].(Validation.HasError)}"  Value="True">
                    <Setter Property="ContentTemplate" >
                        <Setter.Value>
                            <DataTemplate>
                                <Border Height="Auto" Margin="5,0,0,0" Background="#DC000C" CornerRadius="3" DockPanel.Dock="Right">
                                    <TextBlock  Style="{StaticResource textblockErrorTooltip}" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}, Path=Children[1].(Validation.Errors)[0].ErrorContent}"></TextBlock>
                                </Border>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
</UserControl.Resources>

  <StackPanel Orientation="Horizontal" Grid.Row="4">
    <Label  Padding="0,0,20,0">Name:</Label>
    <TextBox  Padding="0,0,10,0" Width="150" x:Name="name" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"></TextBox>
    <ContentControl Style="{StaticResource ContentControlErrorTemplate}">
    </ContentControl>
  </StackPanel>

姓名:

如果你有改进的想法,请告诉我。我不确定它的效率有多高,但它可以工作。

嗨,我不希望每个控件都有一个
装饰器。只需在属性
Validation.HasError上使用数据触发器生成textblock控件,因为正如您所说的
装饰器
作为不同的渲染层,我不希望每个控件都使用
装饰器
。只需在属性
Validation.HasError上使用数据触发器生成textblock控件,因为正如您所说的那样,
装饰器作为不同的渲染层
        <UserControl.Resources>
             <DataTemplate x:Key="errorinfo">
                <TextBlock>Hello World</TextBlock>
            </DataTemplate>
        </UserControl.Resources>
     <StackPanel Orientation="Horizontal" Grid.Row="4">
         <Label  Padding="0,0,20,0">Name:</Label>
            <StackPanel>
              <TextBox  Padding="0,0,10,0" Width="150" x:Name="name" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"></TextBox>
            </StackPanel>
            <ContentControl >
               <ContentControl.Style>
                 <Style  TargetType="ContentControl">
                    <Setter Property="ContentTemplate" Value="{x:Null}"/>
                        <Style.Triggers>
                          <DataTrigger Binding="{Binding ElementName=name, Path=(Validation.HasError)}"  Value="True">
 <Setter Property="ContentTemplate">
                                        <Setter.Value>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding ElementName=name, Path=(Validation.Errors)[0].ErrorContent}"> </TextBlock>
                                            </DataTemplate>
                                        </Setter.Value>
                                    </Setter>
                         </DataTrigger>
                        </Style.Triggers>
                            </Style>
                        </ContentControl.Style>
            </ContentControl>
          </StackPanel>
<UserControl.Resources>
        <Style x:Key="textblockErrorTooltip" TargetType="TextBlock">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="Margin" Value="10 0 10 0" />
        </Style>

        <DataTemplate x:Key="errortemplate">
            <Border Height="Auto" Margin="5,0,0,0" Background="#DC000C" CornerRadius="3" DockPanel.Dock="Right">
                <TextBlock  Style="{StaticResource textblockErrorTooltip}" Text="{Binding Path=(Validation.Errors)[0].ErrorContent}"></TextBlock>
            </Border>
        </DataTemplate>

        <Style x:Key="ContentControlErrorTemplate" TargetType="ContentControl">
            <Setter Property="ContentTemplate" Value="{x:Null}"/>

            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}, Path=Children[1].(Validation.HasError)}"  Value="True">
                    <Setter Property="ContentTemplate" >
                        <Setter.Value>
                            <DataTemplate>
                                <Border Height="Auto" Margin="5,0,0,0" Background="#DC000C" CornerRadius="3" DockPanel.Dock="Right">
                                    <TextBlock  Style="{StaticResource textblockErrorTooltip}" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}, Path=Children[1].(Validation.Errors)[0].ErrorContent}"></TextBlock>
                                </Border>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
</UserControl.Resources>

  <StackPanel Orientation="Horizontal" Grid.Row="4">
    <Label  Padding="0,0,20,0">Name:</Label>
    <TextBox  Padding="0,0,10,0" Width="150" x:Name="name" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"></TextBox>
    <ContentControl Style="{StaticResource ContentControlErrorTemplate}">
    </ContentControl>
  </StackPanel>