実現したいこと
実現したいこと : 下の図のようにエラーメッセージが表示されると下のコントロール(ラベル : 出身地とそのTextBox)が下にずれてほしい
入力後 : エラーメッセージを表示すると下のコントロールと重なっている!!
発生している問題・分からないこと
ControlTemplate内で実現できるかどうかがわからない
該当のソースコード
WPF(XAML)
1<Window x:Class="Test.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:local="clr-namespace:Test" 5 Title="MainWindow" 6 Width="525" 7 Height="350"> 8 <Window.DataContext> 9 <local:MainWindowViewModel /> 10 </Window.DataContext> 11 <Window.Resources> 12 <ControlTemplate x:Key="ValidationTemplate"> 13 <StackPanel> 14 <AdornedElementPlaceholder x:Name="adornedelem" /> 15 <TextBlock Foreground="Red" Text="{Binding AdornedElement.(Validation.Errors)[0].ErrorContent, ElementName=adornedelem}" /> 16 </StackPanel> 17 </ControlTemplate> 18 </Window.Resources> 19 <Grid> 20 <Grid.ColumnDefinitions> 21 <ColumnDefinition Width="*"/> 22 <ColumnDefinition Width="Auto"/> 23 <ColumnDefinition Width="*"/> 24 <ColumnDefinition Width="*"/> 25 </Grid.ColumnDefinitions> 26 <Grid.RowDefinitions> 27 <RowDefinition Height="auto"/> 28 <RowDefinition Height="auto"/> 29 </Grid.RowDefinitions> 30 31 <Label Grid.Row="0" Grid.Column="1" Content="年齢" /> 32 <TextBox Grid.Row="0" Grid.Column="2" 33 Text="{Binding InputString, 34 UpdateSourceTrigger=PropertyChanged}" 35 Validation.ErrorTemplate="{StaticResource ValidationTemplate}" /> 36 37 <Label Grid.Row="1" Grid.Column="1" Content="出身地" /> 38 <TextBox Grid.Row="1" Grid.Column="2" 39 Text="{Binding Area, 40 UpdateSourceTrigger=PropertyChanged}" 41 Validation.ErrorTemplate="{StaticResource ValidationTemplate}" /> 42 </Grid> 43</Window>
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
年齢を入力するTextBoxの下にエラーメッセージ表示用のLabelをVisibility="Collapsed"にしてエラーが発生したらVisibility="Visible"にすればうまくいくのかなと思っているのですがControlTemplate内からエラーメッセージ表示用のLabelのアクセスの仕方がわかりません
名前を付けて指定するようなやり方ではなく他でも使用できるように汎用性があるやり方があれば教えていただきたいです
補足
特になし
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
ValidationAdornerSiteFor
のような得体の知れないものは使わない、基本的なバインドのみの素朴な実装です^^;
テーマ変更時にErrorTemplate
がAdorner
ごと消えてしまう不具合?があるようなのでErrorTemplate
も使いません。
使用側の記述が非常にシンプルで使いやすくなっております。
Label
とTextBox
を一体で扱えるGrid
が不要で項目の追加や入れ替えが容易- アクセスキーに対応かつ
Label.Target
の記述も不要
これならわたしも使いたい(項目が多ければ多いほどうれしいw
xml
1<Window 2 x:Class="Qo1g4oys53jcubr.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Qo1g4oys53jcubr" 6 Width="525" 7 Height="350" 8 ThemeMode="System"> 9 <Window.DataContext> 10 <local:MainWindowViewModel /> 11 </Window.DataContext> 12 <Window.Resources> 13 <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 14 15 <!-- GroupBoxなのがポイント(HeaderedContentControlではダメ) --> 16 <Style x:Key="TextBoxStyle" TargetType="GroupBox"> 17 <Setter Property="Validation.ErrorTemplate" Value="{x:Null}" /> 18 19 <!-- HeaderTemplate・ContentTemplateは華麗にスルー --> 20 <Setter Property="Template"> 21 <Setter.Value> 22 <ControlTemplate TargetType="GroupBox"> 23 <Grid> 24 <Grid.ColumnDefinitions> 25 <ColumnDefinition Width="Auto" SharedSizeGroup="a" /> 26 <ColumnDefinition Width="4" /> 27 <ColumnDefinition /> 28 </Grid.ColumnDefinitions> 29 <Grid.RowDefinitions> 30 <RowDefinition /> 31 <RowDefinition Height="Auto" /> 32 </Grid.RowDefinitions> 33 <Label VerticalAlignment="Center" Content="{TemplateBinding Header}" /> 34 35 <TextBox Grid.Column="2" Text="{Binding Content, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource TemplatedParent}}" /> 36 37 <!-- 本題には関係ないがアクセント色を変えたらオシャレかな?と上にかぶせる雑実装w --> 38 <Border 39 x:Name="border" 40 Grid.Column="2" 41 BorderBrush="{DynamicResource SystemFillColorCriticalBrush}" 42 BorderThickness="0,0,0,2" 43 CornerRadius="{StaticResource ControlCornerRadius}" 44 Visibility="{Binding (Validation.HasError), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}" /> 45 46 <ItemsControl 47 Grid.Row="1" 48 Grid.Column="2" 49 ItemsSource="{Binding (Validation.Errors), RelativeSource={RelativeSource TemplatedParent}}" 50 Visibility="{Binding Visibility, ElementName=border}"> 51 <ItemsControl.ItemTemplate> 52 <DataTemplate> 53 <BulletDecorator TextBlock.Foreground="{DynamicResource SystemFillColorCriticalBrush}"> 54 <BulletDecorator.Bullet> 55 <!-- ⚠️ --> 56 <TextBlock FontFamily="{StaticResource SymbolThemeFontFamily}" Text=" " /> 57 </BulletDecorator.Bullet> 58 <TextBlock Text="{Binding ErrorContent}" TextWrapping="Wrap" /> 59 </BulletDecorator> 60 </DataTemplate> 61 </ItemsControl.ItemTemplate> 62 </ItemsControl> 63 </Grid> 64 </ControlTemplate> 65 </Setter.Value> 66 </Setter> 67 </Style> 68 </Window.Resources> 69 70 <Grid Margin="8"> 71 72 <!-- この中に項目を詰めていくイメージ --> 73 <StackPanel Grid.IsSharedSizeScope="True"> 74 <StackPanel.Resources> 75 76 <!-- スタイルを暗黙的に適用する --> 77 <Style BasedOn="{StaticResource TextBoxStyle}" TargetType="GroupBox" /> 78 </StackPanel.Resources> 79 80 <!-- 超すっきりした記述🤩 --> 81 <GroupBox Content="{Binding Value1, Mode=TwoWay}" Header="値_1" /> 82 <GroupBox Content="{Binding Value2, Mode=TwoWay}" Header="あたい_2" /> 83 </StackPanel> 84 </Grid> 85</Window>
cs
1using System.ComponentModel.DataAnnotations; 2using System.Windows; 3using CommunityToolkit.Mvvm.ComponentModel; 4 5namespace Qo1g4oys53jcubr; 6 7public partial class MainWindow : Window 8{ 9 public MainWindow() => InitializeComponent(); 10} 11 12public partial class MainWindowViewModel : ObservableValidator 13{ 14 [ObservableProperty, NotifyDataErrorInfo] 15 [Required(ErrorMessage = "何か入力してください")] 16 [StringLength(10, ErrorMessage = "10文字以内で入力してください\naaaaaa")] 17 [RegularExpression("[a-z]+", ErrorMessage = "a-zの文字列を入力してください")] 18 private string? value1; 19 20 [ObservableProperty, NotifyDataErrorInfo] 21 [Required(ErrorMessage = "何か入力してください")] 22 private string? value2; 23}
投稿2025/03/29 02:14
総合スコア9990
0
自己解決
色々考えるより数行で対応できたのでコードビハインドで実装しました
まず、自作のTextBlockErrorMessageを作成しました
C#
1コード 2using System; 3using System.Collections.Generic; 4using System.ComponentModel; 5using System.Diagnostics; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows; 10using System.Windows.Controls; 11using System.Windows.Data; 12using System.Windows.Documents; 13using System.Windows.Input; 14using System.Windows.Media; 15using System.Windows.Media.Imaging; 16using System.Windows.Navigation; 17using System.Windows.Shapes; 18 19namespace SeikouCustomControl 20{ 21 /// <summary> 22 /// このカスタム コントロールを XAML ファイルで使用するには、手順 1a または 1b の後、手順 2 に従います。 23 /// 24 /// 手順 1a) 現在のプロジェクトに存在する XAML ファイルでこのカスタム コントロールを使用する場合 25 /// この XmlNamespace 属性を使用場所であるマークアップ ファイルのルート要素に 26 /// 追加します: 27 /// 28 /// xmlns:MyNamespace="clr-namespace:SeikouCustomControl" 29 /// 30 /// 31 /// 手順 1b) 異なるプロジェクトに存在する XAML ファイルでこのカスタム コントロールを使用する場合 32 /// この XmlNamespace 属性を使用場所であるマークアップ ファイルのルート要素に 33 /// 追加します: 34 /// 35 /// xmlns:MyNamespace="clr-namespace:SeikouCustomControl;assembly=SeikouCustomControl" 36 /// 37 /// また、XAML ファイルのあるプロジェクトからこのプロジェクトへのプロジェクト参照を追加し、 38 /// リビルドして、コンパイル エラーを防ぐ必要があります: 39 /// 40 /// ソリューション エクスプローラーで対象のプロジェクトを右クリックし、 41 /// [参照の追加] の [プロジェクト] を選択してから、このプロジェクトを参照し、選択します。 42 /// 43 /// 44 /// 手順 2) 45 /// コントロールを XAML ファイルで使用します。 46 /// 47 /// <MyNamespace:TextBlockErrorMessage/> 48 /// 49 /// </summary> 50 public class TextBlockErrorMessage : TextBlock 51 { 52 static TextBlockErrorMessage() 53 { 54 DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBlockErrorMessage), new FrameworkPropertyMetadata(typeof(TextBlockErrorMessage))); 55 56 } 57 58 public TextBlockErrorMessage() 59 { 60 var descripter = DependencyPropertyDescriptor.FromProperty(TextBlock.TextProperty, typeof(TextBlock)); 61 this.Visibility = Visibility.Collapsed; 62 descripter.AddValueChanged(this, OnTextChanged); 63 } 64 65 private static void OnTextChanged(object? sender, EventArgs e) 66 { 67 var textBlock = (TextBlock)sender; 68 if (string.IsNullOrEmpty(textBlock.Text)) 69 { 70 textBlock.Visibility = Visibility.Collapsed; 71 } 72 else 73 { 74 textBlock.Visibility = Visibility.Visible; 75 } 76 } 77 78 } 79} 80
自作のTextBlockErrorMessageを配置します
WPF
1<Window 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:local="clr-namespace:Test" xmlns:sys="http://schemas.microsoft.com/winfx/2009/xaml" 5 xmlns:scc="clr-namespace:SeikouCustomControl;assembly=SeikouCustomControl" 6 x:Class="Test.MainWindow" 7 Title="MainWindow" 8 Width="525" 9 Height="350"> 10 <Window.Resources> 11 </Window.Resources> 12 <Window.DataContext> 13 <local:MainWindowViewModel /> 14 </Window.DataContext> 15 <Grid> 16 <Grid.ColumnDefinitions> 17 <ColumnDefinition Width="*"/> 18 <ColumnDefinition Width="Auto"/> 19 <ColumnDefinition Width="*"/> 20 <ColumnDefinition Width="*"/> 21 </Grid.ColumnDefinitions> 22 <Grid.RowDefinitions> 23 <RowDefinition Height="auto"/> 24 <RowDefinition Height="auto"/> 25 <RowDefinition Height="auto"/> 26 </Grid.RowDefinitions> 27 28 <Label Grid.Row="0" Grid.Column="1" Content="年齢" /> 29 <TextBox Grid.Row="0" Grid.Column="2" 30 Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}"/> 31 32 <scc:TextBlockErrorMessage Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="100" 33 Text="{Binding InputStringErrorMessage}" 34 /> 35 </Grid> 36</Window>
ViewModelにプロパティを作ります
C#
1using System.ComponentModel.DataAnnotations; 2using System.Runtime.CompilerServices; 3using Test; 4 5namespace Test 6{ 7 public class MainWindowViewModel : ValidateableBase 8 { 9 private string inputString = string.Empty; 10 [Required(ErrorMessage = "年齢 : 何か入力してください")] 11 [StringLength(10, ErrorMessage = "年齢 : \r\n10文字以内で\r\n入力してください")] 12 public string InputString 13 { 14 get { return inputString; } 15 set 16 { 17 SetPropertyWithErrorMessage(ref this.inputString, value); 18 } 19 } 20 21 private string _InputStringErrorMessage = string.Empty; 22 public string InputStringErrorMessage 23 { 24 get { return _InputStringErrorMessage; } 25 private set { this.SetProperty(ref _InputStringErrorMessage, value); } 26 } 27 28 public MainWindowViewModel() 29 { 30 } 31 } 32} 33
次に汎用性を持たせてSetPropertyWithErrorMessageメソッドを作りました
これがベストなのかはわかりません。
C#
1using System.Collections; 2using System.ComponentModel; 3using System.ComponentModel.DataAnnotations; 4using System.Reflection; 5using System.Runtime.CompilerServices; 6 7namespace Test 8{ 9 public abstract class ValidateableBase : BindableBase, INotifyDataErrorInfo 10 { 11 /// <summary> 12 /// プロパティが既に目的の値と一致しているかどうかを確認します。必要な場合のみ、 13 /// プロパティを設定し、リスナーに通知します。 14 /// その後、プロパティの入力値検証を行います。 15 /// </summary> 16 /// <typeparam name="T">プロパティの型。</typeparam> 17 /// <param name="storage">get アクセス操作子と set アクセス操作子両方を使用したプロパティへの参照。</param> 18 /// <param name="value">プロパティに必要な値。</param> 19 /// <param name="propertyName">リスナーに通知するために使用するプロパティの名前。 20 /// この値は省略可能で、 21 /// CallerMemberName をサポートするコンパイラから呼び出す場合に自動的に指定できます。</param> 22 /// <returns>値が変更された場合は true、既存の値が目的の値に一致した場合は 23 /// false です。</returns> 24 protected override bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null) 25 { 26 var isChanged = base.SetProperty(ref storage, value, propertyName); 27 if (isChanged) 28 this.ValidateProperty(value, propertyName); 29 30 return isChanged; 31 } 32 33 protected Dictionary<string, PropertyInfo?> _properties = new Dictionary<string, PropertyInfo?>(); 34 35 protected void SetPropertyWithErrorMessage<T>(ref T storage, T value, [CallerMemberName] String propertyName = null) 36 { 37 this.SetProperty(ref storage, value, propertyName); 38 39 var errorMessage = GetErrorMessage("\r\n", propertyName); 40 41 // プロパティ情報の取得 42 if (!_properties.TryGetValue(propertyName, out var property)) 43 { 44 property = this.GetType().GetProperty(propertyName + "ErrorMessage"); 45 _properties[propertyName] = property; 46 } 47 48 // インスタンスに値を設定 49 property?.SetValue(this, errorMessage); 50 } 51 private string GetErrorMessage(string? messageSeparator, String propertyName) 52 { 53 var errors = (List<string>)GetErrors(propertyName); 54 if (errors != null) 55 { 56 var ss = new string[errors.Count]; 57 errors.CopyTo(ss); 58 return string.Join(messageSeparator, ss); 59 } 60 61 return string.Empty; 62 } 63 64 protected void ValidateProperty(object value, [CallerMemberName] string propertyName = null) 65 { 66 var context = new ValidationContext(this) { MemberName = propertyName }; 67 var validationErrors = new List<ValidationResult>(); 68 if (!Validator.TryValidateProperty(value, context, validationErrors)) 69 { 70 var errors = validationErrors.Select(error => error.ErrorMessage); 71 foreach (var error in errors) 72 { 73 AddError(propertyName, error); 74 } 75 } 76 else 77 { 78 RemoveError(propertyName); 79 } 80 } 81 82 #region 発生中のエラーを保持する処理を実装 83 readonly Dictionary<string, List<string>> _currentErrors = new Dictionary<string, List<string>>(); 84 85 protected void AddError(string propertyName, string error) 86 { 87 if (!_currentErrors.ContainsKey(propertyName)) 88 _currentErrors[propertyName] = new List<string>(); 89 90 if (!_currentErrors[propertyName].Contains(error)) 91 { 92 _currentErrors[propertyName].Add(error); 93 OnErrorsChanged(propertyName); 94 } 95 } 96 97 protected void RemoveError(string propertyName) 98 { 99 if (_currentErrors.ContainsKey(propertyName)) 100 _currentErrors.Remove(propertyName); 101 102 OnErrorsChanged(propertyName); 103 } 104 #endregion 105 106 private void OnErrorsChanged(string propertyName) 107 { 108 var h = this.ErrorsChanged; 109 if (h != null) 110 { 111 h(this, new DataErrorsChangedEventArgs(propertyName)); 112 } 113 } 114 115 #region INotifyDataErrorInfoの実装 116 public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; 117 118 public IEnumerable GetErrors(string propertyName) 119 { 120 if (string.IsNullOrEmpty(propertyName) || 121 !_currentErrors.ContainsKey(propertyName)) 122 return null; 123 124 return _currentErrors[propertyName]; 125 } 126 127 public bool HasErrors 128 { 129 get { return _currentErrors.Count > 0; } 130 } 131 #endregion 132 } 133} 134
投稿2025/03/27 10:59
編集2025/03/28 08:48総合スコア24
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
参考サイトは質問に明示してください。
WPFでの入力値検証・その4 ~ErrorTemplateで検証結果の表示をカスタマイズ~ - SourceChord
年齢を入力するTextBoxの下にエラーメッセージ表示用のLabelをVisibility="Collapsed"にしてエラーが発生したらVisibility="Visible"にすればうまくいくのかなと思っているのですが
TextBox
のControlTemplate
をいじればそんな感じのこともできますが、(無駄に)長くなってしまいます。
単にエラー状態だったら、下マージンを広げるだけでいいのでは?
xml
1<Window 2 x:Class="Qo1g4oys53jcubr.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Qo1g4oys53jcubr" 6 Width="525" 7 Height="350"> 8 <Window.DataContext> 9 <local:MainWindowViewModel /> 10 </Window.DataContext> 11 <Window.Resources> 12 <ControlTemplate x:Key="ValidationTemplate"> 13 <StackPanel> 14 <AdornedElementPlaceholder x:Name="adornedelem" /> 15 <TextBlock Foreground="Red" Text="{Binding AdornedElement.(Validation.Errors)[0].ErrorContent, ElementName=adornedelem}" /> 16 </StackPanel> 17 </ControlTemplate> 18 19 <Style TargetType="TextBox"> 20 <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ValidationTemplate}" /> 21 <Style.Triggers> 22 <Trigger Property="Validation.HasError" Value="True"> 23 <Setter Property="Margin" Value="0,0,0,24" /> 24 </Trigger> 25 </Style.Triggers> 26 </Style> 27 28 <!-- 29 Fluentテーマ適用時 30 [WPF for .NET 9 の新機能 - WPF .NET | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/whats-new/net90?view=netdesktop-9.0#fluent-theme) 31 --> 32 <!--<Style BasedOn="{StaticResource DefaultTextBoxStyle}" TargetType="TextBox"> 33 <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ValidationTemplate}" /> 34 <Style.Triggers> 35 <Trigger Property="Validation.HasError" Value="True"> 36 <Setter Property="Margin" Value="0,0,0,24" /> 37 </Trigger> 38 </Style.Triggers> 39 </Style>--> 40 </Window.Resources> 41 42 <Grid> 43 <Grid.ColumnDefinitions> 44 <ColumnDefinition /> 45 <ColumnDefinition Width="Auto" /> 46 <ColumnDefinition /> 47 <ColumnDefinition /> 48 </Grid.ColumnDefinitions> 49 <Grid.RowDefinitions> 50 <RowDefinition Height="auto" /> 51 <RowDefinition Height="auto" /> 52 </Grid.RowDefinitions> 53 54 <Label Grid.Column="1" Content="年齢" /> 55 <TextBox Grid.Column="2" Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}" /> 56 57 <Label 58 Grid.Row="1" 59 Grid.Column="1" 60 Content="出身地" /> 61 <TextBox 62 Grid.Row="1" 63 Grid.Column="2" 64 Text="{Binding Area, UpdateSourceTrigger=PropertyChanged}" /> 65 </Grid> 66</Window>
cs
1using System.ComponentModel.DataAnnotations; 2using System.Windows; 3using CommunityToolkit.Mvvm.ComponentModel; 4 5namespace Qo1g4oys53jcubr; 6 7public partial class MainWindow : Window 8{ 9 public MainWindow() => InitializeComponent(); 10} 11 12public partial class MainWindowViewModel : ObservableValidator 13{ 14 [ObservableProperty, NotifyDataErrorInfo] 15 [Required(ErrorMessage = "何か入力してください")] 16 [StringLength(10, ErrorMessage = "10文字以内で入力してください")] 17 private string? inputString; 18 19 [ObservableProperty, NotifyDataErrorInfo] 20 [Required(ErrorMessage = "何か入力してください")] 21 private string? area; 22}
NuGet Gallery | CommunityToolkit.Mvvm
MVVM Toolkit の概要 - Community Toolkits for .NET | Microsoft Learn
年齢を入力するTextBoxの下にエラーメッセージ表示用のLabelをVisibility="Collapsed"にしてエラーが発生したらVisibility="Visible"にすればうまくいく
をxamlで愚直に実装しました。
TextBox
分用意しなくてはならずValidationAdornerSite
の設定も面倒なので、1,2個までかなぁという気はします(TextBox
のTemplate
をいじるよりはマシかw
Validation.ValidationAdornerSite 添付プロパティ (System.Windows.Controls) | Microsoft Learn
Validation.ValidationAdornerSiteFor 添付プロパティ (System.Windows.Controls) | Microsoft Learn
Nine Works 例外を利用したデータ検証
厳密にやるなら複数エラーにも対応すべきでしょう。
WPFでの入力値検証・その6 ~複数のエラー表示への対応~ - SourceChord
xml
1<Window 2 x:Class="Qo1g4oys53jcubr.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Qo1g4oys53jcubr" 6 Width="525" 7 Height="350" 8 ThemeMode="System"> 9 <Window.DataContext> 10 <local:MainWindowViewModel /> 11 </Window.DataContext> 12 <Window.Resources> 13 <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 14 15 <Style x:Key="ErrorStyle" TargetType="{x:Type ItemsControl}"> 16 <Setter Property="Validation.ErrorTemplate" Value="{x:Null}" /> 17 <Setter Property="ItemsSource" Value="{Binding (Validation.ValidationAdornerSiteFor).(Validation.Errors), RelativeSource={RelativeSource Self}}" /> 18 <Setter Property="Visibility" Value="{Binding (Validation.ValidationAdornerSiteFor).(Validation.HasError), Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource Self}}" /> 19 <Setter Property="ItemTemplate"> 20 <Setter.Value> 21 <DataTemplate> 22 <BulletDecorator TextBlock.Foreground="Red"> 23 <BulletDecorator.Bullet> 24 <TextBlock Text="! " /> 25 </BulletDecorator.Bullet> 26 <TextBlock Text="{Binding ErrorContent}" TextWrapping="Wrap" /> 27 </BulletDecorator> 28 </DataTemplate> 29 </Setter.Value> 30 </Setter> 31 </Style> 32 </Window.Resources> 33 34 <Grid> 35 <Grid.ColumnDefinitions> 36 <ColumnDefinition Width="Auto" /> 37 <ColumnDefinition /> 38 </Grid.ColumnDefinitions> 39 <Grid.RowDefinitions> 40 <RowDefinition Height="auto" /> 41 <RowDefinition Height="auto" /> 42 </Grid.RowDefinitions> 43 44 <Label Content="年齢" /> 45 <StackPanel Grid.Column="1"> 46 <TextBox 47 Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}" 48 Validation.ErrorTemplate="{x:Null}" 49 Validation.ValidationAdornerSite="{Binding ElementName=inputStringError}" /> 50 <ItemsControl x:Name="inputStringError" Style="{StaticResource ErrorStyle}" /> 51 </StackPanel> 52 53 <Label Grid.Row="1" Content="出身地" /> 54 <StackPanel Grid.Row="1" Grid.Column="1"> 55 <TextBox 56 Text="{Binding Area, UpdateSourceTrigger=PropertyChanged}" 57 Validation.ErrorTemplate="{x:Null}" 58 Validation.ValidationAdornerSite="{Binding ElementName=areaError}" /> 59 <ItemsControl x:Name="areaError" Style="{StaticResource ErrorStyle}" /> 60 </StackPanel> 61 </Grid> 62</Window>
cs
1using System.ComponentModel.DataAnnotations; 2using System.Windows; 3using CommunityToolkit.Mvvm.ComponentModel; 4 5namespace Qo1g4oys53jcubr; 6 7public partial class MainWindow : Window 8{ 9 public MainWindow() => InitializeComponent(); 10} 11 12public partial class MainWindowViewModel : ObservableValidator 13{ 14 [ObservableProperty, NotifyDataErrorInfo] 15 [Required(ErrorMessage = "何か入力してください")] 16 [StringLength(10, ErrorMessage = "10文字以内で入力してください\naaaaaa")] 17 [RegularExpression("[a-z]+", ErrorMessage = "a-zの文字列を入力してください")] 18 private string? inputString; 19 20 [ObservableProperty, NotifyDataErrorInfo] 21 [Required(ErrorMessage = "何か入力してください")] 22 private string? area; 23}
投稿2025/03/26 09:50
編集2025/03/27 14:10総合スコア9990
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2025/03/29 02:14
2025/03/29 02:39
2025/03/29 04:14