Как я могу связать сообщение об ошибке пузыря с TextBox в WPF? - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь сделать хорошее сообщение об ошибке для текстового поля. Текстовое поле:

            <DockPanel DockPanel.Dock="Top">
              <Label Content="Name: "/>
              <TextBox DockPanel.Dock="Top" Text="{Binding Name, ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource textBoxInError}">
              </TextBox>
            </DockPanel>

Я начал с всплывающей подсказки. Стиль ошибки для текстового поля:

    <!-- Style for the error tooltip for fields -->
    <Style x:Key="textBoxInError" TargetType="TextBox">
      <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
          <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>
      </Style.Triggers>
    </Style>

Этого недостаточно, требуется более качественное сообщение. При таком решении ошибка не отображается, пока вы не наведете курсор на поле: enter image description here

Итак, я обнаружил, что могу создать еще один узел, который будет получать сообщение об ошибке из текстового поля:

                <DockPanel DockPanel.Dock="Top">
                  <Label Content="Name: "/>
                  <TextBox DockPanel.Dock="Top" Name="editNodeName" Text="{Binding Name, ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource textBoxInError}">
                  </TextBox>
                  <TextBlock Text="{Binding (Validation.Errors)[0].ErrorContent, ElementName=editNodeName}" TextWrapping="Wrap"/>
                </DockPanel>

Это выглядит очень уродливо и несколько сжимает текстовое поле:
enter image description here

Вот макет того, что я хотел бы вместо этого не требуется, чтобы указатель мыши был видимым :

enter image description here

Это не обязательно должно быть так, но он не должен сжимать флажок или иным образом нарушать форму, и он не должен быть виден, когда нет ошибки.

Можно ли поместить текст сообщения об ошибке рядом с полем? Может быть, как-то привязать позицию к позиции поля, используя привязку?

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

В качестве альтернативы ответу по mm8 вместо всплывающего окна вы можете использовать в качестве ControlTemplate следующее, как источник вдохновения:

<Style x:Key="textBoxInError" TargetType="TextBox">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
    <ControlTemplate>
      <StackPanel Orientation="Vertical">
        <Border CornerRadius="10,10,10,10" Margin="20">
          <Border.Effect>
            <DropShadowEffect Color="#FF474747" />
          </Border.Effect>
          <Border.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
              <GradientStop Color="#FFFF99" Offset="0" />
              <GradientStop Color="#FFFF99" Offset="1" />
            </LinearGradientBrush>
          </Border.Background>
          <Grid Name="grid1">
            <TextBlock Text="Your message here" Padding="10" HorizontalAlignment="Center" Name="lblWarningHeader" VerticalAlignment="Top" FontSize="16"/>
          </Grid>
        </Border>
      </StackPanel>
    </ControlTemplate>
</Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>
    </Style.Triggers>
</Style>
0 голосов
/ 02 марта 2020

Вы можете определить Validation.ErrorTemplate, который содержит Popup, который остается открытым. Примерно так:

<Style x:Key="textBoxInError" TargetType="TextBox">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel>
                    <Popup IsOpen="True" StaysOpen="True" PlacementTarget="{Binding ElementName=border}" Placement="Right">
                        <Border Background="Yellow" BorderBrush="Black" BorderThickness="1">
                            <TextBlock Text="{Binding [0].ErrorContent}" />
                        </Border>
                    </Popup>
                    <Border x:Name="border" BorderBrush="Red" BorderThickness="1">
                        <AdornedElementPlaceholder />
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>
    </Style.Triggers>
</Style>

Вы также можете посмотреть на этот ответ .

...