2つのコンボボックスで同じ色(黒黒)などを選択した場合にワーニングをだす処理を実装したいと思います。
下記のようにSelectedColor00のset内でチェック処理を追加して、同色ならreturnにしてもGUIのコンボボックス上では変更されてしまいます。
WPFの値の検証は「無効な値が入力されたらユーザーに通知する」です。入力できなくするわけではありません。
コンボボックス上は変更されますが、赤枠が出てエラーが分かります。SelectedColor
は変更されません。
データ バインディングの概要 - データの検証 | Microsoft Learn
操作自体をなかったことにすると、なぜできないのかが分からずユーザーが混乱します。
赤枠だけではわかりずらいと思う場合は、より適切な表示に変更できます。
データ バインディングの概要 - 視覚的なフィードバックを提供する | Microsoft Learn
それでは満足できない場合は、そもそも重複しないように選択肢をフィルターしたらどうでしょうか?
方法: ビュー内のデータをフィルター処理する - WPF .NET Framework | Microsoft Learn
ListCollectionView クラス (System.Windows.Data) | Microsoft Learn
xml
1<Window
2 x:Class="Q75875.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:Q75875"
6 Width="800"
7 Height="450"
8 ThemeMode="System">
9 <Window.Resources>
10 <DataTemplate x:Key="circle">
11 <Border Background="Transparent">
12 <Ellipse
13 Width="20"
14 Height="20"
15 HorizontalAlignment="Left"
16 Fill="{Binding}"
17 Stroke="Black" />
18 </Border>
19 </DataTemplate>
20 <DataTemplate x:Key="rect">
21 <Rectangle
22 Height="32"
23 Margin="0,4,0,12"
24 Fill="{Binding}"
25 Stroke="Black" />
26 </DataTemplate>
27 </Window.Resources>
28 <UniformGrid x:Name="uniformGrid" Rows="1">
29 <GroupBox Header="Validation">
30 <StackPanel>
31 <ComboBox
32 ItemTemplate="{StaticResource circle}"
33 ItemsSource="{Binding Colors}"
34 SelectedItem="{Binding SelectedColor00, ValidatesOnExceptions=True}" />
35 <ContentPresenter Content="{Binding SelectedColor00}" ContentTemplate="{StaticResource rect}" />
36
37 <ComboBox
38 ItemTemplate="{StaticResource circle}"
39 ItemsSource="{Binding Colors}"
40 SelectedItem="{Binding SelectedColor01, ValidatesOnExceptions=True}">
41 <Validation.ErrorTemplate>
42 <ControlTemplate>
43 <StackPanel>
44 <Border
45 Width="{Binding ActualWidth, ElementName=e}"
46 BorderBrush="Red"
47 BorderThickness="1">
48 <AdornedElementPlaceholder x:Name="e" />
49 </Border>
50 <TextBlock
51 HorizontalAlignment="Center"
52 Background="Red"
53 Text="{Binding AdornedElement.(Validation.Errors).CurrentItem.ErrorContent, ElementName=e}" />
54 </StackPanel>
55 </ControlTemplate>
56 </Validation.ErrorTemplate>
57 </ComboBox>
58 <ContentPresenter Content="{Binding SelectedColor01}" ContentTemplate="{StaticResource rect}" />
59 </StackPanel>
60 </GroupBox>
61
62 <GroupBox Header="Filter">
63 <StackPanel>
64 <ComboBox
65 ItemTemplate="{StaticResource circle}"
66 ItemsSource="{Binding ColorsA}"
67 SelectedItem="{Binding SelectedColorA}" />
68 <ContentPresenter Content="{Binding SelectedColorA}" ContentTemplate="{StaticResource rect}" />
69
70 <ComboBox
71 ItemTemplate="{StaticResource circle}"
72 ItemsSource="{Binding ColorsB}"
73 SelectedItem="{Binding SelectedColorB}" />
74 <ContentPresenter Content="{Binding SelectedColorB}" ContentTemplate="{StaticResource rect}" />
75 </StackPanel>
76 </GroupBox>
77 </UniformGrid>
78</Window>
cs
1using System.Collections.ObjectModel;
2using System.Windows;
3using System.Windows.Data;
4using System.Windows.Media;
5using CommunityToolkit.Mvvm.ComponentModel;
6
7namespace Q75875;
8
9public partial class MainWindow : Window
10{
11 public MainWindow()
12 {
13 InitializeComponent();
14 DataContext = new ViewModel();
15 }
16}
17
18public partial class ViewModel : ObservableObject
19{
20 public ObservableCollection<Brush> Colors { get; } = [Brushes.Black, Brushes.White, Brushes.Red, Brushes.Blue];
21
22 [ObservableProperty] private Brush? selectedColor00;
23 partial void OnSelectedColor00Changing(Brush? value)
24 {
25 if (value == SelectedColor01) throw new ArgumentException("同じ値は選択できません。");
26 }
27
28 [ObservableProperty] private Brush? selectedColor01;
29 partial void OnSelectedColor01Changing(Brush? value)
30 {
31 if (value == SelectedColor00) throw new ArgumentException("同じ値は選択できません。");
32 }
33
34
35 public ListCollectionView ColorsA { get; }
36 public ListCollectionView ColorsB { get; }
37 [ObservableProperty] private Brush? selectedColorA;
38 [ObservableProperty] private Brush? selectedColorB;
39
40 public ViewModel()
41 {
42 ColorsA = new(Colors) { Filter = x => x != SelectedColorB, };
43 ColorsB = new(Colors) { Filter = x => x != selectedColorA, };
44 ColorsA.CurrentChanged += (_, _) => ColorsB.Refresh();
45 ColorsB.CurrentChanged += (_, _) => ColorsA.Refresh();
46 }
47}
NuGet Gallery | CommunityToolkit.Mvvm

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。