回答編集履歴

2

例を追記

2022/12/21 09:07

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -109,4 +109,123 @@
109
109
  }
110
110
  ```
111
111
 
112
-
112
+ ---
113
+
114
+ > やりたい事は選択した日付からn日後を計算して表示する事でしたが、WPFの基本的なところでハマっていました。
115
+
116
+ `ViewModel`で計算したプロパティを用意するパターンと、`Converter`で計算するパターン例。
117
+ 実際は`ViewModel`レスというわけにもいかないので、この中間くらい(`ViewModel`に必要ない値は`Converter`で計算)になることが多いと思います。
118
+
119
+ ```xml
120
+ <Window
121
+ x:Class="Q9jmho7nu44o3nz.MainWindow"
122
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
123
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
124
+ xmlns:local="clr-namespace:Q9jmho7nu44o3nz"
125
+ xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
126
+ Width="800"
127
+ Height="450">
128
+ <Window.DataContext>
129
+ <local:ViewModel />
130
+ </Window.DataContext>
131
+ <Window.Resources>
132
+ <local:DaysLaterConverter x:Key="DaysLaterConverter" />
133
+ </Window.Resources>
134
+ <UniformGrid>
135
+ <GroupBox Header="ViewModel">
136
+ <StackPanel>
137
+ <DatePicker SelectedDate="{Binding SelectedDate}" />
138
+ <xctk:IntegerUpDown Minimum="0" Value="{Binding DaysLater}" />
139
+ <TextBlock HorizontalAlignment="Right" Text="日後" />
140
+ <TextBox Text="{Binding SelectedDateDaysLater, StringFormat=yyyy/MM/dd, Mode=OneWay}" />
141
+ </StackPanel>
142
+ </GroupBox>
143
+
144
+ <GroupBox Header="Converter">
145
+ <StackPanel>
146
+ <DatePicker x:Name="datePicker" SelectedDate="2023/01/01" />
147
+ <xctk:IntegerUpDown
148
+ x:Name="integerUpDown"
149
+ Minimum="0"
150
+ Value="0" />
151
+ <TextBlock HorizontalAlignment="Right" Text="日後" />
152
+ <TextBox>
153
+ <TextBox.Text>
154
+ <MultiBinding
155
+ Converter="{StaticResource DaysLaterConverter}"
156
+ Mode="OneWay"
157
+ StringFormat="yyyy/MM/dd">
158
+ <Binding ElementName="datePicker" Path="SelectedDate" />
159
+ <Binding ElementName="integerUpDown" Path="Value" />
160
+ </MultiBinding>
161
+ </TextBox.Text>
162
+ </TextBox>
163
+ </StackPanel>
164
+ </GroupBox>
165
+ </UniformGrid>
166
+ </Window>
167
+ ```
168
+
169
+ ```cs
170
+ using System;
171
+ using System.Globalization;
172
+ using System.Windows;
173
+ using System.Windows.Data;
174
+ using CommunityToolkit.Mvvm.ComponentModel;
175
+
176
+ namespace Q9jmho7nu44o3nz
177
+ {
178
+ public class ViewModel : ObservableObject
179
+ {
180
+ // ソースジェネレーター(LangVersion 8以上)を使えれば、もっとすっきり書けるのだが...
181
+ // [ObservableProperty 属性 - .NET Community Toolkit | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/communitytoolkit/mvvm/generators/observableproperty#notifying-dependent-properties)
182
+ public int DaysLater
183
+ {
184
+ get => _DaysLater;
185
+ set
186
+ {
187
+ if (SetProperty(ref _DaysLater, value))
188
+ OnPropertyChanged(nameof(SelectedDateDaysLater));
189
+ }
190
+ }
191
+ private int _DaysLater;
192
+
193
+ public DateTime? SelectedDate
194
+ {
195
+ get => _SelectedDate;
196
+ set
197
+ {
198
+ if (SetProperty(ref _SelectedDate, value))
199
+ OnPropertyChanged(nameof(SelectedDateDaysLater));
200
+ }
201
+ }
202
+ private DateTime? _SelectedDate = DateTime.Parse("2023/01/01");
203
+
204
+ public DateTime? SelectedDateDaysLater => SelectedDate?.AddDays(DaysLater);
205
+ }
206
+
207
+ class DaysLaterConverter : IMultiValueConverter // 雑いw
208
+ {
209
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
210
+ {
211
+ if (values[0] is DateTime d && values[1] is int i)
212
+ return d.AddDays(i);
213
+ return null;
214
+ }
215
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
216
+ }
217
+
218
+
219
+ public partial class MainWindow : Window
220
+ {
221
+ public MainWindow() => InitializeComponent();
222
+ }
223
+ }
224
+ ```
225
+
226
+ [NuGet Gallery | CommunityToolkit.Mvvm 8.0.0](https://www.nuget.org/packages/CommunityToolkit.Mvvm/8.0.0)
227
+ [MVVM Toolkit の概要 - .NET Community Toolkit | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/communitytoolkit/mvvm/)
228
+
229
+ [NuGet Gallery | Extended.Wpf.Toolkit 4.5.0](https://www.nuget.org/packages/Extended.Wpf.Toolkit/4.5.0)
230
+ [IntegerUpDown · xceedsoftware/wpftoolkit Wiki](https://github.com/xceedsoftware/wpftoolkit/wiki/IntegerUpDown)
231
+

1

xaml上で

2022/12/21 04:43

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -13,7 +13,7 @@
13
13
  [csharplang/null-conditional-assignment.md at main · dotnet/csharplang](https://github.com/dotnet/csharplang/blob/main/proposals/null-conditional-assignment.md)
14
14
 
15
15
  ### 案2
16
- 単純な解決法は`TextBox`が先に来るようにする。
16
+ 単純な解決法は、xaml上で`TextBox`が先に来るようにする。
17
17
  しかし順番次第でエラーになることがあるのはやや不安が残る。
18
18
 
19
19
  ### 案3