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

回答編集履歴

1

見直しキャンペーン中

2023/07/23 05:14

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -1,143 +1,143 @@
1
- `DataTemplateSelector`は、`ViewModel`が継承するようなものではありません(通常`View`層に単体で存在します)
2
-
3
- [データ オブジェクトのプロパティに基づく DataTemplate の選択 - WPF | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/data/data-templating-overview#choosing-a-datatemplate-based-on-properties-of-the-data-object)
4
- 作りがだいぶ違いますが、要は「入力値に対して適当なテンプレートを選択して返す」ってだけです(`IValueConverter`なんかもそう)
5
- [方法: バインドされたデータを変換する - WPF | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/data/how-to-convert-bound-data)
6
-
7
- 参考サイトのものを`Livet`で作るとすると、こんな感じでしょうか(`namespace`ごとにまとめていますが、別ファイルです)
8
- ついでに名前を大文字にする~~しょうもない~~コンバーター例(`UppercaseConverter`)も入れました。
9
-
10
- ```xaml
11
- <Window
12
- x:Class="Questions289487.Views.MainWindow"
13
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
14
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
15
- xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
16
- xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
17
- xmlns:v="clr-namespace:Questions289487.Views"
18
- xmlns:vm="clr-namespace:Questions289487.ViewModels"
19
- Width="525"
20
- Height="350">
21
-
22
- <Window.DataContext>
23
- <vm:MainWindowViewModel />
24
- </Window.DataContext>
25
-
26
- <behaviors:Interaction.Triggers>
27
- <behaviors:EventTrigger EventName="ContentRendered">
28
- <l:LivetCallMethodAction MethodName="Initialize" MethodTarget="{Binding}" />
29
- </behaviors:EventTrigger>
30
- <behaviors:EventTrigger EventName="Closed">
31
- <l:DataContextDisposeAction />
32
- </behaviors:EventTrigger>
33
- </behaviors:Interaction.Triggers>
34
-
35
- <Window.Resources>
36
- <DataTemplate x:Key="MyTemplate1">
37
- <TextBlock Background="Aqua" Text="{Binding Name}" />
38
- </DataTemplate>
39
- <DataTemplate x:Key="MyTemplate2">
40
- <TextBlock Background="Gold" Text="{Binding Name}" />
41
- </DataTemplate>
42
-
43
- <v:ComboHeaderTemplateSelector
44
- x:Key="MySelector"
45
- Template1="{StaticResource MyTemplate1}"
46
- Template2="{StaticResource MyTemplate2}" />
47
-
48
- <v:UppercaseConverter x:Key="UppercaseConverter" />
49
- </Window.Resources>
50
-
51
- <StackPanel Margin="10">
52
- <ComboBox ItemsSource="{Binding View}">
53
- <ComboBox.GroupStyle>
54
- <GroupStyle HeaderTemplateSelector="{StaticResource MySelector}" />
55
- </ComboBox.GroupStyle>
56
- <ComboBox.ItemTemplate>
57
- <DataTemplate>
58
- <TextBlock Text="{Binding Title, Converter={StaticResource UppercaseConverter}}" />
59
- </DataTemplate>
60
- </ComboBox.ItemTemplate>
61
- </ComboBox>
62
- </StackPanel>
63
- </Window>
64
- ```
65
-
66
- ```C#
67
- using System.Collections.Generic;
68
- using System.Windows.Data;
69
- using Livet;
70
-
71
- namespace Questions289487.ViewModels
72
- {
73
- // これはModelsにあるべきもの?まあ本題ではないので。。
74
- public class ComboItem
75
- {
76
- public string Title { get; set; }
77
- public string Category { get; set; }
78
- }
79
-
80
- public class MainWindowViewModel : ViewModel
81
- {
82
- private ListCollectionView _View;
83
- public ListCollectionView View
84
- {
85
- get => _View;
86
- set => RaisePropertyChangedIfSet(ref _View, value);
87
- }
88
-
89
- public void Initialize()
90
- {
91
- var items = new List<ComboItem>
92
- {
93
- new ComboItem() { Title = "ichiro", Category = "CategoryA" },
94
- new ComboItem() { Title = "jiro", Category = "CategoryA" },
95
- new ComboItem() { Title = "saburo", Category = "CategoryA" },
96
- new ComboItem() { Title = "momotaro", Category = "CategoryB" },
97
- new ComboItem() { Title = "kintaro", Category = "CategoryB" },
98
- };
99
- View = new ListCollectionView(items);
100
- View.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
101
- }
102
- }
103
- }
104
- ```
105
-
106
- ```C#
107
- using System;
108
- using System.Globalization;
109
- using System.Windows;
110
- using System.Windows.Controls;
111
- using System.Windows.Data;
112
-
113
- namespace Questions289487.Views
114
- {
115
- public partial class MainWindow : Window
116
- {
117
- public MainWindow() => InitializeComponent();
118
- }
119
-
120
- public class ComboHeaderTemplateSelector : DataTemplateSelector
121
- {
122
- public DataTemplate Template1 { get; set; }
123
- public DataTemplate Template2 { get; set; }
124
-
125
- public override DataTemplate SelectTemplate(object item, DependencyObject container)
126
- {
127
- var group = (CollectionViewGroup)item;
128
- if("CategoryA" == group.Name.ToString()) return Template1;
129
- else return Template2;
130
- }
131
- }
132
-
133
- public class UppercaseConverter : IValueConverter
134
- {
135
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
136
- {
137
- var s = (string)value;
138
- return s.ToUpper();
139
- }
140
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
141
- }
142
- }
1
+ `DataTemplateSelector`は、`ViewModel`が継承するようなものではありません(通常`View`層に単体で存在します)
2
+
3
+ [データ オブジェクトのプロパティに基づく DataTemplate の選択 - WPF | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/data/data-templating-overview#choosing-a-datatemplate-based-on-properties-of-the-data-object)
4
+ 作りがだいぶ違いますが、要は「入力値に対して適当なテンプレートを選択して返す」ってだけです(`IValueConverter`なんかもそう)
5
+ [方法: バインドされたデータを変換する - WPF | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/data/how-to-convert-bound-data)
6
+
7
+ 参考サイトのものを`Livet`で作るとすると、こんな感じでしょうか(`namespace`ごとにまとめていますが、別ファイルです)
8
+ ついでに名前を大文字にする~~しょうもない~~コンバーター例(`UppercaseConverter`)も入れました。
9
+
10
+ ```xml
11
+ <Window
12
+ x:Class="Questions289487.Views.MainWindow"
13
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
14
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
15
+ xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
16
+ xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
17
+ xmlns:v="clr-namespace:Questions289487.Views"
18
+ xmlns:vm="clr-namespace:Questions289487.ViewModels"
19
+ Width="525"
20
+ Height="350">
21
+
22
+ <Window.DataContext>
23
+ <vm:MainWindowViewModel />
24
+ </Window.DataContext>
25
+
26
+ <behaviors:Interaction.Triggers>
27
+ <behaviors:EventTrigger EventName="ContentRendered">
28
+ <l:LivetCallMethodAction MethodName="Initialize" MethodTarget="{Binding}" />
29
+ </behaviors:EventTrigger>
30
+ <behaviors:EventTrigger EventName="Closed">
31
+ <l:DataContextDisposeAction />
32
+ </behaviors:EventTrigger>
33
+ </behaviors:Interaction.Triggers>
34
+
35
+ <Window.Resources>
36
+ <DataTemplate x:Key="MyTemplate1">
37
+ <TextBlock Background="Aqua" Text="{Binding Name}" />
38
+ </DataTemplate>
39
+ <DataTemplate x:Key="MyTemplate2">
40
+ <TextBlock Background="Gold" Text="{Binding Name}" />
41
+ </DataTemplate>
42
+
43
+ <v:ComboHeaderTemplateSelector
44
+ x:Key="MySelector"
45
+ Template1="{StaticResource MyTemplate1}"
46
+ Template2="{StaticResource MyTemplate2}" />
47
+
48
+ <v:UppercaseConverter x:Key="UppercaseConverter" />
49
+ </Window.Resources>
50
+
51
+ <StackPanel Margin="10">
52
+ <ComboBox ItemsSource="{Binding View}">
53
+ <ComboBox.GroupStyle>
54
+ <GroupStyle HeaderTemplateSelector="{StaticResource MySelector}" />
55
+ </ComboBox.GroupStyle>
56
+ <ComboBox.ItemTemplate>
57
+ <DataTemplate>
58
+ <TextBlock Text="{Binding Title, Converter={StaticResource UppercaseConverter}}" />
59
+ </DataTemplate>
60
+ </ComboBox.ItemTemplate>
61
+ </ComboBox>
62
+ </StackPanel>
63
+ </Window>
64
+ ```
65
+
66
+ ```cs
67
+ using System.Collections.Generic;
68
+ using System.Windows.Data;
69
+ using Livet;
70
+
71
+ namespace Questions289487.ViewModels
72
+ {
73
+ // これはModelsにあるべきもの?まあ本題ではないので。。
74
+ public class ComboItem
75
+ {
76
+ public string Title { get; set; }
77
+ public string Category { get; set; }
78
+ }
79
+
80
+ public class MainWindowViewModel : ViewModel
81
+ {
82
+ private ListCollectionView _View;
83
+ public ListCollectionView View
84
+ {
85
+ get => _View;
86
+ set => RaisePropertyChangedIfSet(ref _View, value);
87
+ }
88
+
89
+ public void Initialize()
90
+ {
91
+ var items = new List<ComboItem>
92
+ {
93
+ new ComboItem() { Title = "ichiro", Category = "CategoryA" },
94
+ new ComboItem() { Title = "jiro", Category = "CategoryA" },
95
+ new ComboItem() { Title = "saburo", Category = "CategoryA" },
96
+ new ComboItem() { Title = "momotaro", Category = "CategoryB" },
97
+ new ComboItem() { Title = "kintaro", Category = "CategoryB" },
98
+ };
99
+ View = new ListCollectionView(items);
100
+ View.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ```cs
107
+ using System;
108
+ using System.Globalization;
109
+ using System.Windows;
110
+ using System.Windows.Controls;
111
+ using System.Windows.Data;
112
+
113
+ namespace Questions289487.Views
114
+ {
115
+ public partial class MainWindow : Window
116
+ {
117
+ public MainWindow() => InitializeComponent();
118
+ }
119
+
120
+ public class ComboHeaderTemplateSelector : DataTemplateSelector
121
+ {
122
+ public DataTemplate Template1 { get; set; }
123
+ public DataTemplate Template2 { get; set; }
124
+
125
+ public override DataTemplate SelectTemplate(object item, DependencyObject container)
126
+ {
127
+ var group = (CollectionViewGroup)item;
128
+ if("CategoryA" == group.Name.ToString()) return Template1;
129
+ else return Template2;
130
+ }
131
+ }
132
+
133
+ public class UppercaseConverter : IValueConverter
134
+ {
135
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
136
+ {
137
+ var s = (string)value;
138
+ return s.ToUpper();
139
+ }
140
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
141
+ }
142
+ }
143
143
  ```