teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

見直しキャンペーン中

2023/08/12 10:16

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  詳細がわからないので全部適当ですが、ポイントは`ItemViewModel`に`IsEnabled`を用意することです(命名はふさわしいものに変えてください)
2
2
 
3
- `View`に必要なプロパティを供給するのが、`ViewModel`の役割です。
3
+ Viewに必要なプロパティを供給するのが、ViewModelの役割です。
4
4
  もっと複雑な条件だったとしてもやることは同じです。
5
5
 
6
6
  ```xml

1

見直しキャンペーン中

2023/07/23 07:00

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,106 +1,106 @@
1
- 詳細がわからないので全部適当ですが、ポイントは`ItemViewModel`に`IsEnabled`を用意することです(命名はふさわしいものに変えてください)
2
-
3
- `View`に必要なプロパティを供給するのが、`ViewModel`の役割です。
4
- もっと複雑な条件だったとしてもやることは同じです。
5
-
6
- ```xaml
7
- <Window
8
- x:Class="Questions294197.MainWindow"
9
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
10
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
11
- Width="800"
12
- Height="450">
13
- <DockPanel>
14
- <StackPanel DockPanel.Dock="Bottom" Margin="5">
15
- <HeaderedContentControl Header="Name">
16
- <!-- ItemViewModelのNameの編集 -->
17
- <TextBox Text="{Binding Items/Name, UpdateSourceTrigger=PropertyChanged}" />
18
- </HeaderedContentControl>
19
- <HeaderedContentControl Header="IsChecked">
20
- <!-- ItemViewModelのIsCheckedの編集 -->
21
- <CheckBox IsChecked="{Binding Items/IsChecked}" />
22
- </HeaderedContentControl>
23
- <HeaderedContentControl Header="IsEnabled">
24
- <!-- ItemViewModelのIsEnabledは読み取り専用なので編集不可 -->
25
- <CheckBox IsChecked="{Binding Items/IsEnabled, Mode=OneWay}" IsEnabled="False" />
26
- </HeaderedContentControl>
27
- </StackPanel>
28
-
29
- <ListView IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Items}">
30
- <ListView.View>
31
- <GridView>
32
- <GridViewColumn>
33
- <GridViewColumn.CellTemplate>
34
- <DataTemplate>
35
- <!-- CheckBoxのIsEnabledを、ItemViewModelのIsEnabledとバインド -->
36
- <CheckBox IsChecked="{Binding IsChecked}" IsEnabled="{Binding IsEnabled}" />
37
- </DataTemplate>
38
- </GridViewColumn.CellTemplate>
39
- </GridViewColumn>
40
- <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" />
41
- <GridViewColumn DisplayMemberBinding="{Binding IsChecked}" Header="IsChecked" />
42
- <GridViewColumn DisplayMemberBinding="{Binding IsEnabled}" Header="IsEnabled" />
43
- </GridView>
44
- </ListView.View>
45
- </ListView>
46
- </DockPanel>
47
- </Window>
48
- ```
49
-
50
- ```C#
51
- using System.Collections.ObjectModel;
52
- using System.ComponentModel;
53
- using System.Runtime.CompilerServices;
54
- using System.Windows;
55
-
56
- namespace Questions294197
57
- {
58
- public class ItemViewModel : INotifyPropertyChanged
59
- {
60
- private string _Name;
61
- public string Name
62
- {
63
- get => _Name;
64
- set
65
- {
66
- // Nameが変わったときにIsEnabledも変わった(かもしれない)ことを通知
67
- if(Set(ref _Name, value)) OnPropertyChanged(nameof(IsEnabled));
68
- }
69
- }
70
-
71
- // 例えばNameに何か入力がないとチェックを変えられないようにする
72
- public bool IsEnabled => !string.IsNullOrEmpty(Name);
73
-
74
- private bool _IsChecked;
75
- public bool IsChecked { get => _IsChecked; set => Set(ref _IsChecked, value); }
76
-
77
- #region INotifyPropertyChanged
78
- public event PropertyChangedEventHandler PropertyChanged;
79
- protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
80
- {
81
- if(Equals(storage, value)) return false;
82
- storage = value;
83
- OnPropertyChanged(propertyName);
84
- return true;
85
- }
86
- protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
87
- #endregion
88
- }
89
-
90
- public partial class MainWindow : Window
91
- {
92
- public ObservableCollection<ItemViewModel> Items { get; }
93
- public MainWindow()
94
- {
95
- InitializeComponent();
96
- DataContext = this;
97
- Items = new ObservableCollection<ItemViewModel>
98
- {
99
- new ItemViewModel { },
100
- new ItemViewModel { Name = "bbb", },
101
- new ItemViewModel { Name = "ccc", IsChecked = true, },
102
- };
103
- }
104
- }
105
- }
1
+ 詳細がわからないので全部適当ですが、ポイントは`ItemViewModel`に`IsEnabled`を用意することです(命名はふさわしいものに変えてください)
2
+
3
+ `View`に必要なプロパティを供給するのが、`ViewModel`の役割です。
4
+ もっと複雑な条件だったとしてもやることは同じです。
5
+
6
+ ```xml
7
+ <Window
8
+ x:Class="Questions294197.MainWindow"
9
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
10
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
11
+ Width="800"
12
+ Height="450">
13
+ <DockPanel>
14
+ <StackPanel DockPanel.Dock="Bottom" Margin="5">
15
+ <HeaderedContentControl Header="Name">
16
+ <!-- ItemViewModelのNameの編集 -->
17
+ <TextBox Text="{Binding Items/Name, UpdateSourceTrigger=PropertyChanged}" />
18
+ </HeaderedContentControl>
19
+ <HeaderedContentControl Header="IsChecked">
20
+ <!-- ItemViewModelのIsCheckedの編集 -->
21
+ <CheckBox IsChecked="{Binding Items/IsChecked}" />
22
+ </HeaderedContentControl>
23
+ <HeaderedContentControl Header="IsEnabled">
24
+ <!-- ItemViewModelのIsEnabledは読み取り専用なので編集不可 -->
25
+ <CheckBox IsChecked="{Binding Items/IsEnabled, Mode=OneWay}" IsEnabled="False" />
26
+ </HeaderedContentControl>
27
+ </StackPanel>
28
+
29
+ <ListView IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Items}">
30
+ <ListView.View>
31
+ <GridView>
32
+ <GridViewColumn>
33
+ <GridViewColumn.CellTemplate>
34
+ <DataTemplate>
35
+ <!-- CheckBoxのIsEnabledを、ItemViewModelのIsEnabledとバインド -->
36
+ <CheckBox IsChecked="{Binding IsChecked}" IsEnabled="{Binding IsEnabled}" />
37
+ </DataTemplate>
38
+ </GridViewColumn.CellTemplate>
39
+ </GridViewColumn>
40
+ <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" />
41
+ <GridViewColumn DisplayMemberBinding="{Binding IsChecked}" Header="IsChecked" />
42
+ <GridViewColumn DisplayMemberBinding="{Binding IsEnabled}" Header="IsEnabled" />
43
+ </GridView>
44
+ </ListView.View>
45
+ </ListView>
46
+ </DockPanel>
47
+ </Window>
48
+ ```
49
+
50
+ ```cs
51
+ using System.Collections.ObjectModel;
52
+ using System.ComponentModel;
53
+ using System.Runtime.CompilerServices;
54
+ using System.Windows;
55
+
56
+ namespace Questions294197
57
+ {
58
+ public class ItemViewModel : INotifyPropertyChanged
59
+ {
60
+ private string _Name;
61
+ public string Name
62
+ {
63
+ get => _Name;
64
+ set
65
+ {
66
+ // Nameが変わったときにIsEnabledも変わった(かもしれない)ことを通知
67
+ if(Set(ref _Name, value)) OnPropertyChanged(nameof(IsEnabled));
68
+ }
69
+ }
70
+
71
+ // 例えばNameに何か入力がないとチェックを変えられないようにする
72
+ public bool IsEnabled => !string.IsNullOrEmpty(Name);
73
+
74
+ private bool _IsChecked;
75
+ public bool IsChecked { get => _IsChecked; set => Set(ref _IsChecked, value); }
76
+
77
+ #region INotifyPropertyChanged
78
+ public event PropertyChangedEventHandler PropertyChanged;
79
+ protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
80
+ {
81
+ if(Equals(storage, value)) return false;
82
+ storage = value;
83
+ OnPropertyChanged(propertyName);
84
+ return true;
85
+ }
86
+ protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
87
+ #endregion
88
+ }
89
+
90
+ public partial class MainWindow : Window
91
+ {
92
+ public ObservableCollection<ItemViewModel> Items { get; }
93
+ public MainWindow()
94
+ {
95
+ InitializeComponent();
96
+ DataContext = this;
97
+ Items = new ObservableCollection<ItemViewModel>
98
+ {
99
+ new ItemViewModel { },
100
+ new ItemViewModel { Name = "bbb", },
101
+ new ItemViewModel { Name = "ccc", IsChecked = true, },
102
+ };
103
+ }
104
+ }
105
+ }
106
106
  ```