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

回答編集履歴

2

見直しキャンペーン中

2023/08/14 09:53

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  > 相手の発言が左、自分の発言が右に来るようにListBoxのStyleを動的に変更しようとしました。
2
2
 
3
- 正確には`ListBox`の`ItemContainerStyle`で`ListBoxItem`の`Style`を`DataTrigger`で変えるということですね?
3
+ 正確には`ListBox`の`ItemContainerStyle`で`ListBoxItem`の`Style`を`DataTrigger`で変えるということですね?
4
4
 
5
5
  > DataTriggerのValueはバインドできませんでした。(Bindingは使えないというエラーメッセージ)
6
6
 
@@ -16,7 +16,7 @@
16
16
 
17
17
  ---
18
18
 
19
- 前置きが長すぎましたが質問について、「wpf datatrigger value binding」で検索したところ↓がヒットしました。
19
+ 前置きが長すぎましたが質問について、「[wpf datatrigger value binding](https://www.google.co.jp/search?q=wpf+datatrigger+value+binding)」で検索したところ↓がヒットしました。
20
20
  [.net - Using binding for the Value property of DataTrigger condition - Stack Overflow](https://stackoverflow.com/questions/2240421/using-binding-for-the-value-property-of-datatrigger-condition)
21
21
 
22
22
  コンバータが必要なのがちょっと気になります^^;(ほかのアプローチも何かありそうですが

1

見直しキャンペーン中

2023/07/27 16:08

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,183 +1,183 @@
1
- > 相手の発言が左、自分の発言が右に来るようにListBoxのStyleを動的に変更しようとしました。
2
-
3
- 正確には`ListBox`の`ItemContainerStyle`で`ListBoxItem`の`Style`を`DataTrigger`で変えるということですね?
4
-
5
- > DataTriggerのValueはバインドできませんでした。(Bindingは使えないというエラーメッセージ)
6
-
7
- できなかったことも「試したこと」として提示いただけると、やりたいことがはっきりして回答しやすいです。
8
-
9
- > DynamicResourcesを使おうと思ったんですが、調べてもResoucesに単純なstringをバインドする方法が見つかりませんでした。
10
-
11
- こういうことか自信がありませんが、回答コードにはコメントで入れた通り結論はダメでした。
12
-
13
- > ※省略してあります
14
-
15
- もちろん全部出されても困りますが、もう少しないとこちらで再現コードを書く手間と認識があっているかの確信が持てないです^^;
16
-
17
- ---
18
-
19
- 前置きが長すぎましたが質問について、「wpf datatrigger value binding」で検索したところ↓がヒットしました。
20
- [.net - Using binding for the Value property of DataTrigger condition - Stack Overflow](https://stackoverflow.com/questions/2240421/using-binding-for-the-value-property-of-datatrigger-condition)
21
-
22
- コンバータが必要なのがちょっと気になります^^;(ほかのアプローチも何かありそうですが
23
-
24
- ```xaml
25
- <Window
26
- x:Class="Questions345940.MainWindow"
27
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
28
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
29
- xmlns:local="clr-namespace:Questions345940"
30
- xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
31
- xmlns:sys="clr-namespace:System;assembly=mscorlib"
32
- Width="400"
33
- Height="600">
34
- <Window.Resources>
35
- <local:MultiValueEqualityConverter x:Key="multiValueEqualityConverter" />
36
- <!--<sys:String x:Key="myname">dekaribon</sys:String>-->
37
- </Window.Resources>
38
- <Window.DataContext>
39
- <local:DirectMessageViewModel />
40
- </Window.DataContext>
41
- <DockPanel>
42
- <DockPanel DockPanel.Dock="Bottom">
43
- <Button
44
- Command="{Binding SendCommand}"
45
- Content="send"
46
- DockPanel.Dock="Right" />
47
- <RadioButton
48
- Content="dekaribon"
49
- IsChecked="{Binding IsChecked.Value}"
50
- Style="{StaticResource MaterialDesignChoiceChipRadioButton}" />
51
- <RadioButton Content="TN8001" Style="{StaticResource MaterialDesignChoiceChipRadioButton}" />
52
- <TextBox VerticalAlignment="Center" md:HintAssist.Hint="message" />
53
- </DockPanel>
54
-
55
- <ListBox md:ThemeAssist.Theme="Dark" ItemsSource="{Binding MessageInfos}">
56
- <ListBox.ItemContainerStyle>
57
- <Style BasedOn="{StaticResource MaterialDesignListBoxItem}" TargetType="ListBoxItem">
58
- <Setter Property="HorizontalAlignment" Value="Left" />
59
- <Style.Triggers>
60
- <DataTrigger Value="True">
61
- <DataTrigger.Binding>
62
- <MultiBinding Converter="{StaticResource multiValueEqualityConverter}">
63
- <Binding Path="Username" />
64
- <Binding Path="DataContext.Account.Value.Username" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ListBox}}" />
65
- </MultiBinding>
66
- </DataTrigger.Binding>
67
- <Setter Property="HorizontalAlignment" Value="Right" />
68
- </DataTrigger>
69
-
70
- <!-- XDG0062 'DynamicResourceExtension' は、有効なトリガーの条件ではありません。 -->
71
- <!--<DataTrigger Binding="{Binding Username}" Value="{DynamicResource myname}">
72
- <Setter Property="HorizontalAlignment" Value="Right" />
73
- </DataTrigger>-->
74
- </Style.Triggers>
75
- </Style>
76
- </ListBox.ItemContainerStyle>
77
- <ListBox.ItemTemplate>
78
- <DataTemplate>
79
- <md:Card
80
- Margin="2"
81
- Padding="20"
82
- md:ShadowAssist.ShadowDepth="Depth2">
83
- <StackPanel>
84
- <TextBlock HorizontalAlignment="Center" Text="{Binding Username}" />
85
- <Separator Margin="2,5" />
86
- <TextBlock Margin="10,0,0,0" Text="{Binding Message}" />
87
- </StackPanel>
88
- </md:Card>
89
- </DataTemplate>
90
- </ListBox.ItemTemplate>
91
- </ListBox>
92
- </DockPanel>
93
- </Window>
94
- ```
95
-
96
- ```C#
97
- using Reactive.Bindings;
98
- using System;
99
- using System.Globalization;
100
- using System.Linq;
101
- using System.Windows;
102
- using System.Windows.Data;
103
-
104
- namespace Questions345940
105
- {
106
- // [.net - Using binding for the Value property of DataTrigger condition - Stack Overflow](https://stackoverflow.com/questions/2240421/using-binding-for-the-value-property-of-datatrigger-condition)
107
- public class MultiValueEqualityConverter : IMultiValueConverter
108
- {
109
- public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
110
- => values?.All(o => o?.Equals(values[0]) == true) == true || values?.All(o => o == null) == true;
111
- public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
112
- => throw new NotImplementedException();
113
- }
114
-
115
- public class AccountData
116
- {
117
- public string Username { get; set; }
118
- }
119
-
120
- public class DirectMessageItem
121
- {
122
- public string Username { get; set; }
123
- public string Message { get; set; }
124
- }
125
-
126
- public class DirectMessageViewModel
127
- {
128
- public ReactiveProperty<AccountData> Account { get; } = new();
129
- public ReactiveCollection<DirectMessageItem> MessageInfos { get; } = new();
130
- public ReactiveCommand<string> SendCommand { get; } = new();
131
- public ReactiveProperty<bool> IsChecked { get; } = new(true);
132
-
133
- public DirectMessageViewModel()
134
- {
135
- Account.Value = new() { Username = "dekaribon", };
136
- MessageInfos.Add(new() { Username = "dekaribon", Message = "aaa", });
137
- MessageInfos.Add(new() { Username = "TN8001", Message = "bbb", });
138
-
139
- SendCommand.Subscribe(message =>
140
- {
141
- MessageInfos.Add(new()
142
- {
143
- Username = Account.Value.Username,
144
- Message = message,
145
- });
146
- });
147
-
148
- // アカウントチェンジ(不自然なチェンジだが、入れ替わりのテスト
149
- IsChecked.Subscribe(x =>
150
- {
151
- Account.Value = x ? new() { Username = "dekaribon", }
152
- : new() { Username = "TN8001", };
153
- });
154
- }
155
- }
156
-
157
- public partial class MainWindow : Window
158
- {
159
- public MainWindow() => InitializeComponent();
160
- }
161
- }
162
- ```
163
-
164
- ---
165
-
166
- 以降は質問には関係ないんですが、コードを書いていて不思議に思ったことです。
167
-
168
- > あるSNSのアカウントごとにAPIを使用してダイレクトメッセージをLINE風に表示しようとしています。
169
-
170
- > AccountData.Usernameが自分のユーザー名、DirectMessageItem.Usernameが相手のユーザー名になります。
171
-
172
- 私が理解できていないだけかもしれませんが、逆じゃないですか?
173
- 「アカウントごと」というのは、`DirectMessageViewModel`ごとという意味ですよね?
174
- `DirectMessageViewModel`のリストがあり、自分<->Aさん・自分<->Bさん等になるんですよね?
175
- 自分と相手しかいないのであれば、`Account.Username`に自明な自分より相手の名前があったほうが便利そうですが(それとも最初から複垢想定?^^;
176
-
177
- `Account`が`ReactiveProperty`なのも「あれ?」と思いました。
178
- 変更される時があるということですかね?(`DirectMessageViewModel`は一つで使いまわす設計?)
179
-
180
- それを逆手にとって、回答コードは入れ替わりのテストができたのですが^^;
181
-
182
- あと`ThemeAssist.Theme="Dark"`の当て方はあっているんでしょうか?
1
+ > 相手の発言が左、自分の発言が右に来るようにListBoxのStyleを動的に変更しようとしました。
2
+
3
+ 正確には`ListBox`の`ItemContainerStyle`で`ListBoxItem`の`Style`を`DataTrigger`で変えるということですね?
4
+
5
+ > DataTriggerのValueはバインドできませんでした。(Bindingは使えないというエラーメッセージ)
6
+
7
+ できなかったことも「試したこと」として提示いただけると、やりたいことがはっきりして回答しやすいです。
8
+
9
+ > DynamicResourcesを使おうと思ったんですが、調べてもResoucesに単純なstringをバインドする方法が見つかりませんでした。
10
+
11
+ こういうことか自信がありませんが、回答コードにはコメントで入れた通り結論はダメでした。
12
+
13
+ > ※省略してあります
14
+
15
+ もちろん全部出されても困りますが、もう少しないとこちらで再現コードを書く手間と認識があっているかの確信が持てないです^^;
16
+
17
+ ---
18
+
19
+ 前置きが長すぎましたが質問について、「wpf datatrigger value binding」で検索したところ↓がヒットしました。
20
+ [.net - Using binding for the Value property of DataTrigger condition - Stack Overflow](https://stackoverflow.com/questions/2240421/using-binding-for-the-value-property-of-datatrigger-condition)
21
+
22
+ コンバータが必要なのがちょっと気になります^^;(ほかのアプローチも何かありそうですが
23
+
24
+ ```xml
25
+ <Window
26
+ x:Class="Questions345940.MainWindow"
27
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
28
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
29
+ xmlns:local="clr-namespace:Questions345940"
30
+ xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
31
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
32
+ Width="400"
33
+ Height="600">
34
+ <Window.Resources>
35
+ <local:MultiValueEqualityConverter x:Key="multiValueEqualityConverter" />
36
+ <!--<sys:String x:Key="myname">dekaribon</sys:String>-->
37
+ </Window.Resources>
38
+ <Window.DataContext>
39
+ <local:DirectMessageViewModel />
40
+ </Window.DataContext>
41
+ <DockPanel>
42
+ <DockPanel DockPanel.Dock="Bottom">
43
+ <Button
44
+ Command="{Binding SendCommand}"
45
+ Content="send"
46
+ DockPanel.Dock="Right" />
47
+ <RadioButton
48
+ Content="dekaribon"
49
+ IsChecked="{Binding IsChecked.Value}"
50
+ Style="{StaticResource MaterialDesignChoiceChipRadioButton}" />
51
+ <RadioButton Content="TN8001" Style="{StaticResource MaterialDesignChoiceChipRadioButton}" />
52
+ <TextBox VerticalAlignment="Center" md:HintAssist.Hint="message" />
53
+ </DockPanel>
54
+
55
+ <ListBox md:ThemeAssist.Theme="Dark" ItemsSource="{Binding MessageInfos}">
56
+ <ListBox.ItemContainerStyle>
57
+ <Style BasedOn="{StaticResource MaterialDesignListBoxItem}" TargetType="ListBoxItem">
58
+ <Setter Property="HorizontalAlignment" Value="Left" />
59
+ <Style.Triggers>
60
+ <DataTrigger Value="True">
61
+ <DataTrigger.Binding>
62
+ <MultiBinding Converter="{StaticResource multiValueEqualityConverter}">
63
+ <Binding Path="Username" />
64
+ <Binding Path="DataContext.Account.Value.Username" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ListBox}}" />
65
+ </MultiBinding>
66
+ </DataTrigger.Binding>
67
+ <Setter Property="HorizontalAlignment" Value="Right" />
68
+ </DataTrigger>
69
+
70
+ <!-- XDG0062 'DynamicResourceExtension' は、有効なトリガーの条件ではありません。 -->
71
+ <!--<DataTrigger Binding="{Binding Username}" Value="{DynamicResource myname}">
72
+ <Setter Property="HorizontalAlignment" Value="Right" />
73
+ </DataTrigger>-->
74
+ </Style.Triggers>
75
+ </Style>
76
+ </ListBox.ItemContainerStyle>
77
+ <ListBox.ItemTemplate>
78
+ <DataTemplate>
79
+ <md:Card
80
+ Margin="2"
81
+ Padding="20"
82
+ md:ShadowAssist.ShadowDepth="Depth2">
83
+ <StackPanel>
84
+ <TextBlock HorizontalAlignment="Center" Text="{Binding Username}" />
85
+ <Separator Margin="2,5" />
86
+ <TextBlock Margin="10,0,0,0" Text="{Binding Message}" />
87
+ </StackPanel>
88
+ </md:Card>
89
+ </DataTemplate>
90
+ </ListBox.ItemTemplate>
91
+ </ListBox>
92
+ </DockPanel>
93
+ </Window>
94
+ ```
95
+
96
+ ```cs
97
+ using Reactive.Bindings;
98
+ using System;
99
+ using System.Globalization;
100
+ using System.Linq;
101
+ using System.Windows;
102
+ using System.Windows.Data;
103
+
104
+ namespace Questions345940
105
+ {
106
+ // [.net - Using binding for the Value property of DataTrigger condition - Stack Overflow](https://stackoverflow.com/questions/2240421/using-binding-for-the-value-property-of-datatrigger-condition)
107
+ public class MultiValueEqualityConverter : IMultiValueConverter
108
+ {
109
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
110
+ => values?.All(o => o?.Equals(values[0]) == true) == true || values?.All(o => o == null) == true;
111
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
112
+ => throw new NotImplementedException();
113
+ }
114
+
115
+ public class AccountData
116
+ {
117
+ public string Username { get; set; }
118
+ }
119
+
120
+ public class DirectMessageItem
121
+ {
122
+ public string Username { get; set; }
123
+ public string Message { get; set; }
124
+ }
125
+
126
+ public class DirectMessageViewModel
127
+ {
128
+ public ReactiveProperty<AccountData> Account { get; } = new();
129
+ public ReactiveCollection<DirectMessageItem> MessageInfos { get; } = new();
130
+ public ReactiveCommand<string> SendCommand { get; } = new();
131
+ public ReactiveProperty<bool> IsChecked { get; } = new(true);
132
+
133
+ public DirectMessageViewModel()
134
+ {
135
+ Account.Value = new() { Username = "dekaribon", };
136
+ MessageInfos.Add(new() { Username = "dekaribon", Message = "aaa", });
137
+ MessageInfos.Add(new() { Username = "TN8001", Message = "bbb", });
138
+
139
+ SendCommand.Subscribe(message =>
140
+ {
141
+ MessageInfos.Add(new()
142
+ {
143
+ Username = Account.Value.Username,
144
+ Message = message,
145
+ });
146
+ });
147
+
148
+ // アカウントチェンジ(不自然なチェンジだが、入れ替わりのテスト
149
+ IsChecked.Subscribe(x =>
150
+ {
151
+ Account.Value = x ? new() { Username = "dekaribon", }
152
+ : new() { Username = "TN8001", };
153
+ });
154
+ }
155
+ }
156
+
157
+ public partial class MainWindow : Window
158
+ {
159
+ public MainWindow() => InitializeComponent();
160
+ }
161
+ }
162
+ ```
163
+
164
+ ---
165
+
166
+ 以降は質問には関係ないんですが、コードを書いていて不思議に思ったことです。
167
+
168
+ > あるSNSのアカウントごとにAPIを使用してダイレクトメッセージをLINE風に表示しようとしています。
169
+
170
+ > AccountData.Usernameが自分のユーザー名、DirectMessageItem.Usernameが相手のユーザー名になります。
171
+
172
+ 私が理解できていないだけかもしれませんが、逆じゃないですか?
173
+ 「アカウントごと」というのは、`DirectMessageViewModel`ごとという意味ですよね?
174
+ `DirectMessageViewModel`のリストがあり、自分<->Aさん・自分<->Bさん等になるんですよね?
175
+ 自分と相手しかいないのであれば、`Account.Username`に自明な自分より相手の名前があったほうが便利そうですが(それとも最初から複垢想定?^^;
176
+
177
+ `Account`が`ReactiveProperty`なのも「あれ?」と思いました。
178
+ 変更される時があるということですかね?(`DirectMessageViewModel`は一つで使いまわす設計?)
179
+
180
+ それを逆手にとって、回答コードは入れ替わりのテストができたのですが^^;
181
+
182
+ あと`ThemeAssist.Theme="Dark"`の当て方はあっているんでしょうか?
183
183
  回答コードだと`ListBox`の選択が見えない(これは結果OKっぽい)のと、スクロールバーの色が見えなくなりました^^;