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

回答編集履歴

2

見直しキャンペーン中

2023/07/29 06:42

投稿

TN8001
TN8001

スコア10114

answer CHANGED
@@ -1,229 +1,220 @@
1
- なんか堂々巡りですね^^;
2
- どうもprismユーザーと話が合わないのは、私がわかってないだけなんでしょうか?(だったらいいのですが^^;
3
-
4
- 理屈上は`RelativeSource`で`Window`とでもすれば引っ張ってこれますが、そんなのイヤすぎますよね?
5
-
6
- そもそもガッツリprismしている場合、`UserControl`の表示は↓のようになりませんか?(Prism Full App(.NET Core)テンプレートより)
7
- ```xaml
8
- <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.ContentRegion}" />
9
- ```
10
- `DependencyProperty`を設定するタイミングもないです(まあやりようはあるんでしょうけど)
11
-
12
- 一度Prism Full App(.NET Core)テンプレートを作っていただいて、`ViewA`・`ViewAViewModel`・`MessageService`の関係を見ていただけたらいいと思います。
13
-
14
- ---
15
-
16
- 例がないと話の前提が合いませんので雑に作りました(`Func<T,R>`が気持ち悪いのは気にしないでください^^;
17
- [NuGet Gallery | Prism.DryIoc 8.1.97](https://www.nuget.org/packages/Prism.DryIoc/8.1.97)
18
- [NuGet Gallery | ReactiveProperty 7.12.0](https://www.nuget.org/packages/ReactiveProperty/7.12.0)
19
-
20
- `TextBox`と`TextBlock`の組が4つあります。どれも動作は同じです(入力値の小文字が大文字になって表示される)
21
-
22
- 4つのうち1つだけおかしい(異質な)ものがあります。
23
-
24
- MainWindow.xaml
25
- ```xaml
26
- <Window
27
- x:Class="Questions362091.Views.MainWindow"
28
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
29
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
30
- xmlns:prism="http://prismlibrary.com/"
31
- xmlns:views="clr-namespace:Questions362091.Views"
32
- Width="525"
33
- SizeToContent="Height">
34
- <StackPanel>
35
-
36
- <GroupBox Header="ベタ置き">
37
- <StackPanel>
38
- <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
39
- <TextBlock HorizontalAlignment="Center" Text="↓" />
40
- <TextBlock Text="{Binding Output.Value}" />
41
- </StackPanel>
42
- </GroupBox>
43
-
44
- <GroupBox Header="UserControl1">
45
- <views:UserControl1 />
46
- </GroupBox>
47
-
48
- <GroupBox Header="PrismUserControl1">
49
- <ContentControl prism:RegionManager.RegionName="ContentRegion" />
50
- </GroupBox>
51
-
52
- <GroupBox Header="UserControl2">
53
- <views:UserControl2 Converter="{Binding Converter}" Input="{Binding Input.Value}" />
54
- </GroupBox>
55
- </StackPanel>
56
- </Window>
57
- ```
58
-
59
- UserControl1.xaml
60
- ```xaml
61
- <UserControl
62
- x:Class="Questions362091.Views.UserControl1"
63
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
64
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
65
- <StackPanel>
66
- <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
67
- <TextBlock HorizontalAlignment="Center" Text="↓" />
68
- <TextBlock Text="{Binding Output.Value}" />
69
- </StackPanel>
70
- </UserControl>
71
- ```
72
-
73
- PrismUserControl1.xaml
74
- ```xaml
75
- <UserControl
76
- x:Class="Questions362091.Views.PrismUserControl1"
77
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
78
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
79
- <StackPanel>
80
- <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
81
- <TextBlock HorizontalAlignment="Center" Text="↓" />
82
- <TextBlock Text="{Binding Output.Value}" />
83
- </StackPanel>
84
- </UserControl>
85
- ```
86
-
87
- UserControl2.xaml
88
- ```xaml
89
- <UserControl
90
- x:Class="Questions362091.Views.UserControl2"
91
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
92
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
93
- xmlns:views="clr-namespace:Questions362091.Views">
94
- <StackPanel>
95
- <TextBox Text="{Binding Input, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type views:UserControl2}}}" />
96
- <TextBlock HorizontalAlignment="Center" Text="↓" />
97
- <TextBlock Text="{Binding Output, RelativeSource={RelativeSource AncestorType={x:Type views:UserControl2}}}" />
98
- </StackPanel>
99
- </UserControl>
100
- ```
101
-
102
- UserControl2.xaml.cs
103
- ```C#
104
- using System;
105
- using System.Windows;
106
- using System.Windows.Controls;
107
-
108
- namespace Questions362091.Views
109
- {
110
- public partial class UserControl2 : UserControl
111
- {
112
- public string Input { get => (string)GetValue(InputProperty); set => SetValue(InputProperty, value); }
113
- public static readonly DependencyProperty InputProperty = DependencyProperty.Register(nameof(Input), typeof(string), typeof(UserControl2), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, InputChanged));
114
- private static void InputChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
115
- {
116
- if (d is UserControl2 userControl2)
117
- userControl2.Output = userControl2.Converter?.Invoke((string)e.NewValue);
118
- }
119
-
120
- public string Output { get => (string)GetValue(OutputProperty); protected set => SetValue(OutputPropertyKey, value); }
121
- private static readonly DependencyPropertyKey OutputPropertyKey = DependencyProperty.RegisterReadOnly(nameof(Output), typeof(string), typeof(UserControl2), new());
122
- public static readonly DependencyProperty OutputProperty = OutputPropertyKey.DependencyProperty;
123
-
124
- public Func<string, string> Converter { get => (Func<string, string>)GetValue(ConverterProperty); set => SetValue(ConverterProperty, value); }
125
- public static readonly DependencyProperty ConverterProperty = DependencyProperty.Register(nameof(Converter), typeof(Func<string, string>), typeof(UserControl2), new((Func<string, string>)(s => s)));
126
-
127
- public UserControl2() => InitializeComponent();
128
- }
129
- }
130
- ```
131
-
132
- MainWindowViewModel.cs
133
- ```C#
134
- using Prism.Mvvm;
135
- using Prism.Regions;
136
- using Questions362091.Models;
137
- using Reactive.Bindings;
138
- using Reactive.Bindings.Extensions;
139
- using System;
140
-
141
- namespace Questions362091.ViewModels
142
- {
143
- public class MainWindowViewModel : BindableBase
144
- {
145
- public ReactiveProperty<string> Input { get; }
146
- public ReadOnlyReactiveProperty<string> Output { get; }
147
- public Func<string, string> Converter => model.Converter;
148
-
149
- private readonly Model model;
150
-
151
- public MainWindowViewModel(Model model, IRegionManager regionManager)
152
- {
153
- this.model = model;
154
- Input = model.Input.ToReactivePropertyAsSynchronized(x => x.Value);
155
- Output = model.Output.ToReadOnlyReactiveProperty();
156
- }
157
- }
158
- }
159
- ```
160
-
161
- PrismUserControl1ViewModel.cs
162
- ```C#
163
- using Prism.Mvvm;
164
- using Questions362091.Models;
165
- using Reactive.Bindings;
166
- using Reactive.Bindings.Extensions;
167
-
168
- namespace Questions362091.ViewModels
169
- {
170
- public class PrismUserControl1ViewModel : BindableBase
171
- {
172
- public ReactiveProperty<string> Input { get; }
173
- public ReadOnlyReactiveProperty<string> Output { get; }
174
-
175
- public PrismUserControl1ViewModel(Model model)
176
- {
177
- Input = model.Input.ToReactivePropertyAsSynchronized(x => x.Value);
178
- Output = model.Output.ToReadOnlyReactiveProperty();
179
- }
180
- }
181
- }
182
- ```
183
-
184
- Model.cs
185
- ```C#
186
- using Reactive.Bindings;
187
- using System;
188
- using System.Reactive.Linq;
189
-
190
- namespace Questions362091.Models
191
- {
192
- public class Model
193
- {
194
- public ReactivePropertySlim<string> Input { get; } = new();
195
- public ReadOnlyReactivePropertySlim<string> Output { get; }
196
- public Func<string, string> Converter { get; } = s => s?.ToUpper();
197
-
198
- public Model() => Output = Input.Select(Converter).ToReadOnlyReactivePropertySlim();
199
- }
200
- }
201
- ```
202
-
203
- App.xaml.cs
204
- ```C#
205
- using Prism.Ioc;
206
- using Prism.Regions;
207
- using Questions362091.Models;
208
- using Questions362091.Views;
209
- using System.Windows;
210
-
211
- namespace Questions362091
212
- {
213
- public partial class App
214
- {
215
- protected override Window CreateShell() => Container.Resolve<MainWindow>();
216
- protected override void OnInitialized()
217
- {
218
- base.OnInitialized();
219
- var regionManager = Container.Resolve<IRegionManager>();
220
- regionManager.RegisterViewWithRegion("ContentRegion", typeof(PrismUserControl1));
221
- }
222
- protected override void RegisterTypes(IContainerRegistry containerRegistry)
223
- {
224
- containerRegistry.RegisterSingleton<Model>();
225
- containerRegistry.RegisterForNavigation<PrismUserControl1>();
226
- }
227
- }
228
- }
1
+ なんか堂々巡りですね^^;
2
+ どうもprismユーザーと話が合わないのは、私がわかってないだけなんでしょうか?(だったらいいのですが^^;
3
+
4
+ 理屈上は`RelativeSource`で`Window`とでもすれば引っ張ってこれますが、そんなのイヤすぎますよね?
5
+
6
+ そもそもガッツリprismしている場合、`UserControl`の表示は↓のようになりませんか?(Prism Full App(.NET Core)テンプレートより)
7
+ ```xml
8
+ <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.ContentRegion}" />
9
+ ```
10
+ `DependencyProperty`を設定するタイミングもないです(まあやりようはあるんでしょうけど)
11
+
12
+ 一度Prism Full App(.NET Core)テンプレートを作っていただいて、`ViewA`・`ViewAViewModel`・`MessageService`の関係を見ていただけたらいいと思います。
13
+
14
+ ---
15
+
16
+ 例がないと話の前提が合いませんので雑に作りました(`Func<T,R>`が気持ち悪いのは気にしないでください^^;
17
+ [NuGet Gallery | Prism.DryIoc 8.1.97](https://www.nuget.org/packages/Prism.DryIoc/8.1.97)
18
+ [NuGet Gallery | ReactiveProperty 7.12.0](https://www.nuget.org/packages/ReactiveProperty/7.12.0)
19
+
20
+ `TextBox`と`TextBlock`の組が4つあります。どれも動作は同じです(入力値の小文字が大文字になって表示される)
21
+
22
+ 4つのうち1つだけおかしい(異質な)ものがあります。
23
+
24
+ ```xml:MainWindow.xaml
25
+ <Window
26
+ x:Class="Questions362091.Views.MainWindow"
27
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
28
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
29
+ xmlns:prism="http://prismlibrary.com/"
30
+ xmlns:views="clr-namespace:Questions362091.Views"
31
+ Width="525"
32
+ SizeToContent="Height">
33
+ <StackPanel>
34
+
35
+ <GroupBox Header="ベタ置き">
36
+ <StackPanel>
37
+ <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
38
+ <TextBlock HorizontalAlignment="Center" Text="↓" />
39
+ <TextBlock Text="{Binding Output.Value}" />
40
+ </StackPanel>
41
+ </GroupBox>
42
+
43
+ <GroupBox Header="UserControl1">
44
+ <views:UserControl1 />
45
+ </GroupBox>
46
+
47
+ <GroupBox Header="PrismUserControl1">
48
+ <ContentControl prism:RegionManager.RegionName="ContentRegion" />
49
+ </GroupBox>
50
+
51
+ <GroupBox Header="UserControl2">
52
+ <views:UserControl2 Converter="{Binding Converter}" Input="{Binding Input.Value}" />
53
+ </GroupBox>
54
+ </StackPanel>
55
+ </Window>
56
+ ```
57
+
58
+ ```xml:UserControl1.xaml
59
+ <UserControl
60
+ x:Class="Questions362091.Views.UserControl1"
61
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
62
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
63
+ <StackPanel>
64
+ <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
65
+ <TextBlock HorizontalAlignment="Center" Text="↓" />
66
+ <TextBlock Text="{Binding Output.Value}" />
67
+ </StackPanel>
68
+ </UserControl>
69
+ ```
70
+
71
+ ```xml:PrismUserControl1.xaml
72
+ <UserControl
73
+ x:Class="Questions362091.Views.PrismUserControl1"
74
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
75
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
76
+ <StackPanel>
77
+ <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
78
+ <TextBlock HorizontalAlignment="Center" Text="↓" />
79
+ <TextBlock Text="{Binding Output.Value}" />
80
+ </StackPanel>
81
+ </UserControl>
82
+ ```
83
+
84
+ ```xml:UserControl2.xaml
85
+ <UserControl
86
+ x:Class="Questions362091.Views.UserControl2"
87
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
88
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
89
+ xmlns:views="clr-namespace:Questions362091.Views">
90
+ <StackPanel>
91
+ <TextBox Text="{Binding Input, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type views:UserControl2}}}" />
92
+ <TextBlock HorizontalAlignment="Center" Text="↓" />
93
+ <TextBlock Text="{Binding Output, RelativeSource={RelativeSource AncestorType={x:Type views:UserControl2}}}" />
94
+ </StackPanel>
95
+ </UserControl>
96
+ ```
97
+
98
+ ```cs:UserControl2.xaml.cs
99
+ using System;
100
+ using System.Windows;
101
+ using System.Windows.Controls;
102
+
103
+ namespace Questions362091.Views
104
+ {
105
+ public partial class UserControl2 : UserControl
106
+ {
107
+ public string Input { get => (string)GetValue(InputProperty); set => SetValue(InputProperty, value); }
108
+ public static readonly DependencyProperty InputProperty = DependencyProperty.Register(nameof(Input), typeof(string), typeof(UserControl2), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, InputChanged));
109
+ private static void InputChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
110
+ {
111
+ if (d is UserControl2 userControl2)
112
+ userControl2.Output = userControl2.Converter?.Invoke((string)e.NewValue);
113
+ }
114
+
115
+ public string Output { get => (string)GetValue(OutputProperty); protected set => SetValue(OutputPropertyKey, value); }
116
+ private static readonly DependencyPropertyKey OutputPropertyKey = DependencyProperty.RegisterReadOnly(nameof(Output), typeof(string), typeof(UserControl2), new());
117
+ public static readonly DependencyProperty OutputProperty = OutputPropertyKey.DependencyProperty;
118
+
119
+ public Func<string, string> Converter { get => (Func<string, string>)GetValue(ConverterProperty); set => SetValue(ConverterProperty, value); }
120
+ public static readonly DependencyProperty ConverterProperty = DependencyProperty.Register(nameof(Converter), typeof(Func<string, string>), typeof(UserControl2), new((Func<string, string>)(s => s)));
121
+
122
+ public UserControl2() => InitializeComponent();
123
+ }
124
+ }
125
+ ```
126
+
127
+ ```cs:MainWindowViewModel.cs
128
+ using Prism.Mvvm;
129
+ using Prism.Regions;
130
+ using Questions362091.Models;
131
+ using Reactive.Bindings;
132
+ using Reactive.Bindings.Extensions;
133
+ using System;
134
+
135
+ namespace Questions362091.ViewModels
136
+ {
137
+ public class MainWindowViewModel : BindableBase
138
+ {
139
+ public ReactiveProperty<string> Input { get; }
140
+ public ReadOnlyReactiveProperty<string> Output { get; }
141
+ public Func<string, string> Converter => model.Converter;
142
+
143
+ private readonly Model model;
144
+
145
+ public MainWindowViewModel(Model model, IRegionManager regionManager)
146
+ {
147
+ this.model = model;
148
+ Input = model.Input.ToReactivePropertyAsSynchronized(x => x.Value);
149
+ Output = model.Output.ToReadOnlyReactiveProperty();
150
+ }
151
+ }
152
+ }
153
+ ```
154
+
155
+ ```cs:PrismUserControl1ViewModel.cs
156
+ using Prism.Mvvm;
157
+ using Questions362091.Models;
158
+ using Reactive.Bindings;
159
+ using Reactive.Bindings.Extensions;
160
+
161
+ namespace Questions362091.ViewModels
162
+ {
163
+ public class PrismUserControl1ViewModel : BindableBase
164
+ {
165
+ public ReactiveProperty<string> Input { get; }
166
+ public ReadOnlyReactiveProperty<string> Output { get; }
167
+
168
+ public PrismUserControl1ViewModel(Model model)
169
+ {
170
+ Input = model.Input.ToReactivePropertyAsSynchronized(x => x.Value);
171
+ Output = model.Output.ToReadOnlyReactiveProperty();
172
+ }
173
+ }
174
+ }
175
+ ```
176
+
177
+ ```cs:Model.cs
178
+ using Reactive.Bindings;
179
+ using System;
180
+ using System.Reactive.Linq;
181
+
182
+ namespace Questions362091.Models
183
+ {
184
+ public class Model
185
+ {
186
+ public ReactivePropertySlim<string> Input { get; } = new();
187
+ public ReadOnlyReactivePropertySlim<string> Output { get; }
188
+ public Func<string, string> Converter { get; } = s => s?.ToUpper();
189
+
190
+ public Model() => Output = Input.Select(Converter).ToReadOnlyReactivePropertySlim();
191
+ }
192
+ }
193
+ ```
194
+
195
+ ```cs:App.xaml.cs
196
+ using Prism.Ioc;
197
+ using Prism.Regions;
198
+ using Questions362091.Models;
199
+ using Questions362091.Views;
200
+ using System.Windows;
201
+
202
+ namespace Questions362091
203
+ {
204
+ public partial class App
205
+ {
206
+ protected override Window CreateShell() => Container.Resolve<MainWindow>();
207
+ protected override void OnInitialized()
208
+ {
209
+ base.OnInitialized();
210
+ var regionManager = Container.Resolve<IRegionManager>();
211
+ regionManager.RegisterViewWithRegion("ContentRegion", typeof(PrismUserControl1));
212
+ }
213
+ protected override void RegisterTypes(IContainerRegistry containerRegistry)
214
+ {
215
+ containerRegistry.RegisterSingleton<Model>();
216
+ containerRegistry.RegisterForNavigation<PrismUserControl1>();
217
+ }
218
+ }
219
+ }
229
220
  ```

1

2021/10/02 09:56

投稿

TN8001
TN8001

スコア10114

answer CHANGED
@@ -9,4 +9,221 @@
9
9
  ```
10
10
  `DependencyProperty`を設定するタイミングもないです(まあやりようはあるんでしょうけど)
11
11
 
12
- 一度Prism Full App(.NET Core)テンプレートを作っていただいて、`ViewA`・`ViewAViewModel`・`MessageService`の関係を見ていただけたらいいと思います。
12
+ 一度Prism Full App(.NET Core)テンプレートを作っていただいて、`ViewA`・`ViewAViewModel`・`MessageService`の関係を見ていただけたらいいと思います。
13
+
14
+ ---
15
+
16
+ 例がないと話の前提が合いませんので雑に作りました(`Func<T,R>`が気持ち悪いのは気にしないでください^^;
17
+ [NuGet Gallery | Prism.DryIoc 8.1.97](https://www.nuget.org/packages/Prism.DryIoc/8.1.97)
18
+ [NuGet Gallery | ReactiveProperty 7.12.0](https://www.nuget.org/packages/ReactiveProperty/7.12.0)
19
+
20
+ `TextBox`と`TextBlock`の組が4つあります。どれも動作は同じです(入力値の小文字が大文字になって表示される)
21
+
22
+ 4つのうち1つだけおかしい(異質な)ものがあります。
23
+
24
+ MainWindow.xaml
25
+ ```xaml
26
+ <Window
27
+ x:Class="Questions362091.Views.MainWindow"
28
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
29
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
30
+ xmlns:prism="http://prismlibrary.com/"
31
+ xmlns:views="clr-namespace:Questions362091.Views"
32
+ Width="525"
33
+ SizeToContent="Height">
34
+ <StackPanel>
35
+
36
+ <GroupBox Header="ベタ置き">
37
+ <StackPanel>
38
+ <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
39
+ <TextBlock HorizontalAlignment="Center" Text="↓" />
40
+ <TextBlock Text="{Binding Output.Value}" />
41
+ </StackPanel>
42
+ </GroupBox>
43
+
44
+ <GroupBox Header="UserControl1">
45
+ <views:UserControl1 />
46
+ </GroupBox>
47
+
48
+ <GroupBox Header="PrismUserControl1">
49
+ <ContentControl prism:RegionManager.RegionName="ContentRegion" />
50
+ </GroupBox>
51
+
52
+ <GroupBox Header="UserControl2">
53
+ <views:UserControl2 Converter="{Binding Converter}" Input="{Binding Input.Value}" />
54
+ </GroupBox>
55
+ </StackPanel>
56
+ </Window>
57
+ ```
58
+
59
+ UserControl1.xaml
60
+ ```xaml
61
+ <UserControl
62
+ x:Class="Questions362091.Views.UserControl1"
63
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
64
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
65
+ <StackPanel>
66
+ <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
67
+ <TextBlock HorizontalAlignment="Center" Text="↓" />
68
+ <TextBlock Text="{Binding Output.Value}" />
69
+ </StackPanel>
70
+ </UserControl>
71
+ ```
72
+
73
+ PrismUserControl1.xaml
74
+ ```xaml
75
+ <UserControl
76
+ x:Class="Questions362091.Views.PrismUserControl1"
77
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
78
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
79
+ <StackPanel>
80
+ <TextBox Text="{Binding Input.Value, UpdateSourceTrigger=PropertyChanged}" />
81
+ <TextBlock HorizontalAlignment="Center" Text="↓" />
82
+ <TextBlock Text="{Binding Output.Value}" />
83
+ </StackPanel>
84
+ </UserControl>
85
+ ```
86
+
87
+ UserControl2.xaml
88
+ ```xaml
89
+ <UserControl
90
+ x:Class="Questions362091.Views.UserControl2"
91
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
92
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
93
+ xmlns:views="clr-namespace:Questions362091.Views">
94
+ <StackPanel>
95
+ <TextBox Text="{Binding Input, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type views:UserControl2}}}" />
96
+ <TextBlock HorizontalAlignment="Center" Text="↓" />
97
+ <TextBlock Text="{Binding Output, RelativeSource={RelativeSource AncestorType={x:Type views:UserControl2}}}" />
98
+ </StackPanel>
99
+ </UserControl>
100
+ ```
101
+
102
+ UserControl2.xaml.cs
103
+ ```C#
104
+ using System;
105
+ using System.Windows;
106
+ using System.Windows.Controls;
107
+
108
+ namespace Questions362091.Views
109
+ {
110
+ public partial class UserControl2 : UserControl
111
+ {
112
+ public string Input { get => (string)GetValue(InputProperty); set => SetValue(InputProperty, value); }
113
+ public static readonly DependencyProperty InputProperty = DependencyProperty.Register(nameof(Input), typeof(string), typeof(UserControl2), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, InputChanged));
114
+ private static void InputChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
115
+ {
116
+ if (d is UserControl2 userControl2)
117
+ userControl2.Output = userControl2.Converter?.Invoke((string)e.NewValue);
118
+ }
119
+
120
+ public string Output { get => (string)GetValue(OutputProperty); protected set => SetValue(OutputPropertyKey, value); }
121
+ private static readonly DependencyPropertyKey OutputPropertyKey = DependencyProperty.RegisterReadOnly(nameof(Output), typeof(string), typeof(UserControl2), new());
122
+ public static readonly DependencyProperty OutputProperty = OutputPropertyKey.DependencyProperty;
123
+
124
+ public Func<string, string> Converter { get => (Func<string, string>)GetValue(ConverterProperty); set => SetValue(ConverterProperty, value); }
125
+ public static readonly DependencyProperty ConverterProperty = DependencyProperty.Register(nameof(Converter), typeof(Func<string, string>), typeof(UserControl2), new((Func<string, string>)(s => s)));
126
+
127
+ public UserControl2() => InitializeComponent();
128
+ }
129
+ }
130
+ ```
131
+
132
+ MainWindowViewModel.cs
133
+ ```C#
134
+ using Prism.Mvvm;
135
+ using Prism.Regions;
136
+ using Questions362091.Models;
137
+ using Reactive.Bindings;
138
+ using Reactive.Bindings.Extensions;
139
+ using System;
140
+
141
+ namespace Questions362091.ViewModels
142
+ {
143
+ public class MainWindowViewModel : BindableBase
144
+ {
145
+ public ReactiveProperty<string> Input { get; }
146
+ public ReadOnlyReactiveProperty<string> Output { get; }
147
+ public Func<string, string> Converter => model.Converter;
148
+
149
+ private readonly Model model;
150
+
151
+ public MainWindowViewModel(Model model, IRegionManager regionManager)
152
+ {
153
+ this.model = model;
154
+ Input = model.Input.ToReactivePropertyAsSynchronized(x => x.Value);
155
+ Output = model.Output.ToReadOnlyReactiveProperty();
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ PrismUserControl1ViewModel.cs
162
+ ```C#
163
+ using Prism.Mvvm;
164
+ using Questions362091.Models;
165
+ using Reactive.Bindings;
166
+ using Reactive.Bindings.Extensions;
167
+
168
+ namespace Questions362091.ViewModels
169
+ {
170
+ public class PrismUserControl1ViewModel : BindableBase
171
+ {
172
+ public ReactiveProperty<string> Input { get; }
173
+ public ReadOnlyReactiveProperty<string> Output { get; }
174
+
175
+ public PrismUserControl1ViewModel(Model model)
176
+ {
177
+ Input = model.Input.ToReactivePropertyAsSynchronized(x => x.Value);
178
+ Output = model.Output.ToReadOnlyReactiveProperty();
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ Model.cs
185
+ ```C#
186
+ using Reactive.Bindings;
187
+ using System;
188
+ using System.Reactive.Linq;
189
+
190
+ namespace Questions362091.Models
191
+ {
192
+ public class Model
193
+ {
194
+ public ReactivePropertySlim<string> Input { get; } = new();
195
+ public ReadOnlyReactivePropertySlim<string> Output { get; }
196
+ public Func<string, string> Converter { get; } = s => s?.ToUpper();
197
+
198
+ public Model() => Output = Input.Select(Converter).ToReadOnlyReactivePropertySlim();
199
+ }
200
+ }
201
+ ```
202
+
203
+ App.xaml.cs
204
+ ```C#
205
+ using Prism.Ioc;
206
+ using Prism.Regions;
207
+ using Questions362091.Models;
208
+ using Questions362091.Views;
209
+ using System.Windows;
210
+
211
+ namespace Questions362091
212
+ {
213
+ public partial class App
214
+ {
215
+ protected override Window CreateShell() => Container.Resolve<MainWindow>();
216
+ protected override void OnInitialized()
217
+ {
218
+ base.OnInitialized();
219
+ var regionManager = Container.Resolve<IRegionManager>();
220
+ regionManager.RegisterViewWithRegion("ContentRegion", typeof(PrismUserControl1));
221
+ }
222
+ protected override void RegisterTypes(IContainerRegistry containerRegistry)
223
+ {
224
+ containerRegistry.RegisterSingleton<Model>();
225
+ containerRegistry.RegisterForNavigation<PrismUserControl1>();
226
+ }
227
+ }
228
+ }
229
+ ```