feat: add validation errors to textbox.

This commit is contained in:
rabbitism 2023-05-05 02:21:33 +08:00
parent aee8042af8
commit 127bd1446a
4 changed files with 139 additions and 80 deletions

View File

@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:system="clr-namespace:System;assembly=netstandard"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
mc:Ignorable="d"> mc:Ignorable="d">
@ -41,6 +42,23 @@
InnerLeftContent="http://" InnerLeftContent="http://"
InnerRightContent=".com" InnerRightContent=".com"
IsEnabled="False" /> IsEnabled="False" />
<TextBox
Width="500"
InnerLeftContent="http://"
InnerRightContent=".com">
<DataValidationErrors.Error>
<system:Exception />
</DataValidationErrors.Error>
</TextBox>
<TextBox
Width="500"
Classes="Bordered"
InnerLeftContent="http://"
InnerRightContent=".com">
<DataValidationErrors.Error>
<system:Exception />
</DataValidationErrors.Error>
</TextBox>
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>
</UserControl> </UserControl>

View File

@ -27,7 +27,7 @@
<DataTemplate> <DataTemplate>
<ItemsControl <ItemsControl
x:DataType="DataValidationErrors" x:DataType="DataValidationErrors"
Foreground="{DynamicResource DataValidationErrorForeground}" Foreground="{DynamicResource DataValidationErrorsForeground}"
ItemsSource="{Binding}"> ItemsSource="{Binding}">
<ItemsControl.Styles> <ItemsControl.Styles>
<Style Selector="TextBlock"> <Style Selector="TextBlock">

View File

@ -96,7 +96,6 @@
<Setter Property="TextBox.FontSize" Value="14" /> <Setter Property="TextBox.FontSize" Value="14" />
<Setter Property="TextBox.Cursor" Value="Ibeam" /> <Setter Property="TextBox.Cursor" Value="Ibeam" />
<Setter Property="TextBox.CaretBrush" Value="{DynamicResource TextBoxTextCaretBrush}" /> <Setter Property="TextBox.CaretBrush" Value="{DynamicResource TextBoxTextCaretBrush}" />
<Setter Property="TextBox.MinHeight" Value="{DynamicResource TextBoxWrapperDefaultHeight}" />
<Setter Property="TextBox.Padding" Value="{DynamicResource TextBoxContentPadding}" /> <Setter Property="TextBox.Padding" Value="{DynamicResource TextBoxContentPadding}" />
<Setter Property="TextBox.VerticalContentAlignment" Value="Center" /> <Setter Property="TextBox.VerticalContentAlignment" Value="Center" />
<Setter Property="TextBox.FocusAdorner" Value="{x:Null}" /> <Setter Property="TextBox.FocusAdorner" Value="{x:Null}" />
@ -104,79 +103,82 @@
<Setter Property="TextBox.ContextFlyout" Value="{StaticResource DefaultTextBoxContextFlyout}" /> <Setter Property="TextBox.ContextFlyout" Value="{StaticResource DefaultTextBoxContextFlyout}" />
<Setter Property="TextBox.Template"> <Setter Property="TextBox.Template">
<ControlTemplate TargetType="TextBox"> <ControlTemplate TargetType="TextBox">
<Border <DataValidationErrors>
Name="PART_ContentPresenterBorder" <Border
Background="{TemplateBinding Background}" Name="PART_ContentPresenterBorder"
BorderBrush="{TemplateBinding BorderBrush}" MinHeight="{DynamicResource TextBoxWrapperDefaultHeight}"
BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}"> BorderBrush="{TemplateBinding BorderBrush}"
<Grid Margin="{TemplateBinding Padding}" ColumnDefinitions="Auto,*,Auto, Auto, Auto"> BorderThickness="{TemplateBinding BorderThickness}"
<ContentPresenter CornerRadius="{TemplateBinding CornerRadius}">
Grid.Column="0" <Grid Margin="{TemplateBinding Padding}" ColumnDefinitions="Auto,*,Auto, Auto, Auto">
Padding="{DynamicResource TextBoxInnerLeftContentPadding}" <ContentPresenter
VerticalAlignment="Center" Grid.Column="0"
Content="{TemplateBinding InnerLeftContent}" Padding="{DynamicResource TextBoxInnerLeftContentPadding}"
Foreground="{DynamicResource TextBoxInnerForeground}" VerticalAlignment="Center"
IsVisible="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=InnerLeftContent, Converter={x:Static ObjectConverters.IsNotNull}}" /> Content="{TemplateBinding InnerLeftContent}"
<ScrollViewer Foreground="{DynamicResource TextBoxInnerForeground}"
Grid.Column="1" IsVisible="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=InnerLeftContent, Converter={x:Static ObjectConverters.IsNotNull}}" />
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}" <ScrollViewer
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" Grid.Column="1"
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}" AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"> HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
<Panel> IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
<TextBlock VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
Name="PART_Watermark" <Panel>
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" <TextBlock
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Name="PART_Watermark"
IsVisible="{TemplateBinding Text, HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Converter={x:Static StringConverters.IsNullOrEmpty}}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Opacity="0.5" IsVisible="{TemplateBinding Text,
Text="{TemplateBinding Watermark}" Converter={x:Static StringConverters.IsNullOrEmpty}}"
TextAlignment="{TemplateBinding TextAlignment}" Opacity="0.5"
TextWrapping="{TemplateBinding TextWrapping}" /> Text="{TemplateBinding Watermark}"
<TextPresenter TextAlignment="{TemplateBinding TextAlignment}"
Name="PART_TextPresenter" TextWrapping="{TemplateBinding TextWrapping}" />
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" <TextPresenter
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Name="PART_TextPresenter"
CaretBrush="{TemplateBinding CaretBrush}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
CaretIndex="{TemplateBinding CaretIndex}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
LineHeight="{TemplateBinding LineHeight}" CaretBrush="{TemplateBinding CaretBrush}"
PasswordChar="{TemplateBinding PasswordChar}" CaretIndex="{TemplateBinding CaretIndex}"
RevealPassword="{TemplateBinding RevealPassword}" LineHeight="{TemplateBinding LineHeight}"
SelectionBrush="{TemplateBinding SelectionBrush}" PasswordChar="{TemplateBinding PasswordChar}"
SelectionEnd="{TemplateBinding SelectionEnd}" RevealPassword="{TemplateBinding RevealPassword}"
SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}" SelectionBrush="{TemplateBinding SelectionBrush}"
SelectionStart="{TemplateBinding SelectionStart}" SelectionEnd="{TemplateBinding SelectionEnd}"
Text="{TemplateBinding Text, SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}"
Mode=TwoWay}" SelectionStart="{TemplateBinding SelectionStart}"
TextAlignment="{TemplateBinding TextAlignment}" Text="{TemplateBinding Text,
TextWrapping="{TemplateBinding TextWrapping}" /> Mode=TwoWay}"
</Panel> TextAlignment="{TemplateBinding TextAlignment}"
</ScrollViewer> TextWrapping="{TemplateBinding TextWrapping}" />
<Button </Panel>
Name="PART_ClearButton" </ScrollViewer>
Grid.Column="2" <Button
Command="{Binding $parent[TextBox].Clear}" Name="PART_ClearButton"
IsVisible="False" Grid.Column="2"
Theme="{StaticResource InputClearButton}" /> Command="{Binding $parent[TextBox].Clear}"
<ToggleButton IsVisible="False"
Name="PART_RevealButton" Theme="{StaticResource InputClearButton}" />
Grid.Column="3" <ToggleButton
Margin="4,0,0,0" Name="PART_RevealButton"
IsChecked="{TemplateBinding RevealPassword, Grid.Column="3"
Mode=TwoWay}" Margin="4,0,0,0"
IsVisible="False" IsChecked="{TemplateBinding RevealPassword,
Theme="{StaticResource InputToggleButton}" /> Mode=TwoWay}"
<ContentPresenter IsVisible="False"
Grid.Column="4" Theme="{StaticResource InputToggleButton}" />
Padding="{DynamicResource TextBoxInnerRightContentPadding}" <ContentPresenter
VerticalAlignment="Center" Grid.Column="4"
Content="{TemplateBinding InnerRightContent}" Padding="{DynamicResource TextBoxInnerRightContentPadding}"
Foreground="{DynamicResource TextBoxInnerForeground}" VerticalAlignment="Center"
IsVisible="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=InnerRightContent, Converter={x:Static ObjectConverters.IsNotNull}}" /> Content="{TemplateBinding InnerRightContent}"
</Grid> Foreground="{DynamicResource TextBoxInnerForeground}"
</Border> IsVisible="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=InnerRightContent, Converter={x:Static ObjectConverters.IsNotNull}}" />
</Grid>
</Border>
</DataValidationErrors>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
@ -196,6 +198,26 @@
<Style Selector="^:disabled"> <Style Selector="^:disabled">
<Setter Property="TextBox.Foreground" Value="{DynamicResource TextBoxDisabledForeground}" /> <Setter Property="TextBox.Foreground" Value="{DynamicResource TextBoxDisabledForeground}" />
</Style> </Style>
<Style Selector="^:error">
<Style Selector="^ /template/ Border#PART_ContentPresenterBorder">
<Setter Property="Background" Value="{DynamicResource DataValidationErrorsBackground}" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
<Style Selector="^:pointerover /template/ Border#PART_ContentPresenterBorder">
<Setter Property="Border.Background" Value="{DynamicResource DataValidationErrorsPointerOverBackground}" />
<Setter Property="Border.BorderBrush" Value="Transparent" />
</Style>
<Style Selector="^:pressed /template/ Border#PART_ContentPresenterBorder">
<Setter Property="Border.Background" Value="{DynamicResource DataValidationErrorsPressedBackground}" />
<Setter Property="Border.BorderBrush" Value="Transparent" />
</Style>
<Style Selector="^:focus /template/ Border#PART_ContentPresenterBorder">
<Setter Property="Border.Background" Value="{DynamicResource DataValidationErrorsSelectedBackground}" />
<Setter Property="Border.BorderBrush" Value="{DynamicResource DataValidationErrorsSelectedBorderBrush}" />
</Style>
</Style>
<Style Selector="^.clearButton, ^.ClearButton"> <Style Selector="^.clearButton, ^.ClearButton">
<Style Selector="^[AcceptsReturn=False][IsReadOnly=False]:focus:not(:empty) /template/ Button#PART_ClearButton"> <Style Selector="^[AcceptsReturn=False][IsReadOnly=False]:focus:not(:empty) /template/ Button#PART_ClearButton">
<Setter Property="Button.IsVisible" Value="True" /> <Setter Property="Button.IsVisible" Value="True" />
@ -209,11 +231,11 @@
<Setter Property="ToggleButton.IsVisible" Value="True" /> <Setter Property="ToggleButton.IsVisible" Value="True" />
</Style> </Style>
</Style> </Style>
<Style Selector="^.Large"> <Style Selector="^.Large /template/ Border#PART_ContentPresenterBorder">
<Setter Property="TextBox.MinHeight" Value="{DynamicResource TextBoxWrapperLargeHeight}" /> <Setter Property="MinHeight" Value="{DynamicResource TextBoxWrapperLargeHeight}" />
</Style> </Style>
<Style Selector="^.Small"> <Style Selector="^.Small /template/ Border#PART_ContentPresenterBorder">
<Setter Property="TextBox.MinHeight" Value="{DynamicResource TextBoxWrapperSmallHeight}" /> <Setter Property="MinHeight" Value="{DynamicResource TextBoxWrapperSmallHeight}" />
</Style> </Style>
<Style Selector="^.Bordered"> <Style Selector="^.Bordered">
@ -231,6 +253,25 @@
<Setter Property="TextBox.Background" Value="{DynamicResource TextBoxDisabledBackground}" /> <Setter Property="TextBox.Background" Value="{DynamicResource TextBoxDisabledBackground}" />
<Setter Property="TextBox.BorderBrush" Value="{DynamicResource TextBoxDisabledBorderBrush}" /> <Setter Property="TextBox.BorderBrush" Value="{DynamicResource TextBoxDisabledBorderBrush}" />
</Style> </Style>
<Style Selector="^:error">
<Style Selector="^ /template/ Border#PART_ContentPresenterBorder">
<Setter Property="Background" Value="{DynamicResource DataValidationErrorsBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource DataValidationErrorsBorderBrush}" />
</Style>
<Style Selector="^:pointerover /template/ Border#PART_ContentPresenterBorder">
<Setter Property="Border.Background" Value="{DynamicResource DataValidationErrorsPointerOverBackground}" />
<Setter Property="Border.BorderBrush" Value="{DynamicResource DataValidationErrorsPointerOverBorderBrush}" />
</Style>
<Style Selector="^:pressed /template/ Border#PART_ContentPresenterBorder">
<Setter Property="Border.Background" Value="{DynamicResource DataValidationErrorsPressedBackground}" />
<Setter Property="Border.BorderBrush" Value="{DynamicResource DataValidationErrorsPressedBorderBrush}" />
</Style>
<Style Selector="^:focus /template/ Border#PART_ContentPresenterBorder">
<Setter Property="Border.Background" Value="{DynamicResource DataValidationErrorsSelectedBackground}" />
<Setter Property="Border.BorderBrush" Value="{DynamicResource DataValidationErrorsSelectedBorderBrush}" />
</Style>
</Style>
</Style> </Style>
</ControlTheme> </ControlTheme>
</ResourceDictionary> </ResourceDictionary>

View File

@ -1,6 +1,6 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ResourceDictionary xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Add Resources Here --> <!-- Add Resources Here -->
<SolidColorBrush x:Key="DataValidationErrorForeground" Color="#FFF93920" /> <SolidColorBrush x:Key="DataValidationErrorsForeground" Color="#FFF93920" />
<SolidColorBrush x:Key="DataValidationErrorsBackground" Color="#FFFEF2ED" /> <SolidColorBrush x:Key="DataValidationErrorsBackground" Color="#FFFEF2ED" />
<SolidColorBrush x:Key="DataValidationErrorsBorderBrush" Color="#FFFEF2ED" /> <SolidColorBrush x:Key="DataValidationErrorsBorderBrush" Color="#FFFEF2ED" />
<SolidColorBrush x:Key="DataValidationErrorsPointerOverBackground" Color="#FFFEDDD2" /> <SolidColorBrush x:Key="DataValidationErrorsPointerOverBackground" Color="#FFFEDDD2" />