CalendarDatePicker: DateTimeOffset<->DateTime-Konvertierung per Converter
CI / build-and-test (push) Canceled after 0s
CI / build-and-test (push) Canceled after 0s
CalendarDatePicker.SelectedDate ist (WPF-Toolkit-Ursprung) DateTime?, nicht DateTimeOffset? wie beim eingebauten DatePicker - Avalonia bietet dafuer keine automatische Konvertierung. Ohne Converter blieb das Feld leer und ein Klick auf einen Kalendertag warf eine InvalidCastException. Betraf auch die schon bestehenden Bindings in WithdrawStudentDialog und CreateLetterDialog, nur bislang unbemerkt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace LehrerApp.Desktop.Converters;
|
||||
|
||||
/// <summary>`CalendarDatePicker.SelectedDate` ist (anders als der eingebaute `DatePicker`) vom
|
||||
/// WPF-Toolkit übernommenes `DateTime?`, während Datumsfelder in dieser Codebasis durchgängig
|
||||
/// `DateTimeOffset`(?) sind. Avalonia bietet dafür keine automatische Konvertierung
|
||||
/// (`TypeUtilities.TryConvert`/`TryConvertImplicit` unterstützen `DateTime`↔`DateTimeOffset`
|
||||
/// nicht) — ohne diesen Converter bleibt die Bindung beim Anzeigen stumm leer und wirft beim
|
||||
/// Zurückschreiben eine `InvalidCastException`.</summary>
|
||||
public sealed class DateTimeOffsetToDateTimeConverter : IValueConverter
|
||||
{
|
||||
public static readonly DateTimeOffsetToDateTimeConverter Instance = new();
|
||||
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
|
||||
value is DateTimeOffset offset ? offset.DateTime : null;
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
|
||||
value is DateTime dateTime ? new DateTimeOffset(DateTime.SpecifyKind(dateTime, DateTimeKind.Local)) : null;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.ClassTeacher"
|
||||
xmlns:conv="clr-namespace:LehrerApp.Desktop.Converters"
|
||||
x:Class="LehrerApp.Desktop.Views.ClassTeacher.ClassTeacherAbsencesView"
|
||||
x:DataType="vm:ClassTeacherDetailsViewModel">
|
||||
|
||||
@@ -45,9 +46,9 @@
|
||||
<ComboBoxItem Content="Heute"/><ComboBoxItem Content="Letzte 7 Tage"/><ComboBoxItem Content="Letzte 30 Tage"/>
|
||||
</ComboBox>
|
||||
<TextBlock Grid.Column="1" Text="von" VerticalAlignment="Center" Opacity="0.6"/>
|
||||
<CalendarDatePicker Grid.Column="2" SelectedDate="{Binding StartDate}" HorizontalAlignment="Stretch"/>
|
||||
<CalendarDatePicker Grid.Column="2" SelectedDate="{Binding StartDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}" HorizontalAlignment="Stretch"/>
|
||||
<TextBlock Grid.Column="3" Text="bis" VerticalAlignment="Center" Opacity="0.6"/>
|
||||
<CalendarDatePicker Grid.Column="4" SelectedDate="{Binding EndDate}" HorizontalAlignment="Stretch"/>
|
||||
<CalendarDatePicker Grid.Column="4" SelectedDate="{Binding EndDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}" HorizontalAlignment="Stretch"/>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto" ColumnSpacing="8">
|
||||
<TextBox Grid.Column="0" Text="{Binding StudentFilter, Mode=TwoWay}" PlaceholderText="Schüler*in filtern…"/>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.ClassTeacher"
|
||||
xmlns:svm="clr-namespace:LehrerApp.Desktop.ViewModels.Students"
|
||||
xmlns:conv="clr-namespace:LehrerApp.Desktop.Converters"
|
||||
x:Class="LehrerApp.Desktop.Views.ClassTeacher.ClassTeacherRegisterView"
|
||||
x:DataType="vm:ClassTeacherDetailsViewModel">
|
||||
|
||||
@@ -104,9 +105,9 @@
|
||||
<ComboBoxItem Content="Heute"/><ComboBoxItem Content="Letzte 7 Tage"/><ComboBoxItem Content="Letzte 30 Tage"/>
|
||||
</ComboBox>
|
||||
<TextBlock Grid.Column="1" Text="von" VerticalAlignment="Center" Opacity="0.6"/>
|
||||
<CalendarDatePicker Grid.Column="2" SelectedDate="{Binding StartDate}" HorizontalAlignment="Stretch"/>
|
||||
<CalendarDatePicker Grid.Column="2" SelectedDate="{Binding StartDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}" HorizontalAlignment="Stretch"/>
|
||||
<TextBlock Grid.Column="3" Text="bis" VerticalAlignment="Center" Opacity="0.6"/>
|
||||
<CalendarDatePicker Grid.Column="4" SelectedDate="{Binding EndDate}" HorizontalAlignment="Stretch"/>
|
||||
<CalendarDatePicker Grid.Column="4" SelectedDate="{Binding EndDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}" HorizontalAlignment="Stretch"/>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto" ColumnSpacing="8">
|
||||
<TextBox Grid.Column="0" Text="{Binding StudentFilter, Mode=TwoWay}" PlaceholderText="Schüler*in filtern…"/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Groups"
|
||||
xmlns:conv="clr-namespace:LehrerApp.Desktop.Converters"
|
||||
x:Class="LehrerApp.Desktop.Views.Groups.WebUntisLessonAbsenceComparisonDialog"
|
||||
x:DataType="vm:WebUntisLessonAbsenceComparisonViewModel"
|
||||
Title="Fehlzeiten je Unterricht mit WebUntis abgleichen" Width="1000" Height="640"
|
||||
@@ -12,9 +13,9 @@
|
||||
FontSize="12" Opacity="0.65" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="8">
|
||||
<CalendarDatePicker SelectedDate="{Binding StartDate}"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding StartDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}"/>
|
||||
<TextBlock Text="bis" VerticalAlignment="Center"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding EndDate}"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding EndDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}"/>
|
||||
<Button Content="Fehlzeiten laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="2" ColumnDefinitions="Auto,1.2*,1.2*,80,80,1.1*,1.1*" ColumnSpacing="8" Margin="4,0">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Groups"
|
||||
xmlns:conv="clr-namespace:LehrerApp.Desktop.Converters"
|
||||
x:Class="LehrerApp.Desktop.Views.Groups.WithdrawStudentDialog"
|
||||
x:DataType="vm:WithdrawStudentDialogViewModel"
|
||||
Title="Schüler austragen"
|
||||
@@ -23,8 +24,8 @@
|
||||
|
||||
<StackPanel Spacing="5">
|
||||
<TextBlock Text="Austrittsdatum" FontSize="12" Opacity="0.7"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding SelectedDate}"
|
||||
DisplayDateStart="{Binding EarliestDate}"
|
||||
<CalendarDatePicker SelectedDate="{Binding SelectedDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}"
|
||||
DisplayDateStart="{Binding EarliestDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}"
|
||||
HorizontalAlignment="Stretch"/>
|
||||
<TextBlock Text="{Binding DateError}" Foreground="Red" FontSize="12"
|
||||
IsVisible="{Binding DateError, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Planning"
|
||||
xmlns:svc="clr-namespace:LehrerApp.Desktop.Services"
|
||||
xmlns:conv="clr-namespace:LehrerApp.Desktop.Converters"
|
||||
x:Class="LehrerApp.Desktop.Views.Planning.WebUntisTimetableImportDialog"
|
||||
x:DataType="vm:WebUntisTimetableImportViewModel"
|
||||
Title="Stundenplan aus WebUntis" Width="820" Height="650"
|
||||
@@ -18,7 +19,7 @@
|
||||
<DataTemplate x:DataType="svc:UntisTeacherDto"><TextBlock Text="{Binding DisplayName}"/></DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<CalendarDatePicker Grid.Column="1" SelectedDate="{Binding WeekDate}"/>
|
||||
<CalendarDatePicker Grid.Column="1" SelectedDate="{Binding WeekDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}"/>
|
||||
<Button Grid.Column="2" Content="Woche laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
||||
</Grid>
|
||||
<ScrollViewer Grid.Row="2">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Students"
|
||||
xmlns:conv="clr-namespace:LehrerApp.Desktop.Converters"
|
||||
x:Class="LehrerApp.Desktop.Views.Students.CreateLetterDialog"
|
||||
x:DataType="vm:CreateLetterDialogViewModel"
|
||||
Title="PDF-Brief erstellen" Width="580" Height="760"
|
||||
@@ -40,7 +41,7 @@
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="2" Spacing="4">
|
||||
<TextBlock Text="Briefdatum *" FontSize="12" Opacity="0.7"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding LetterDate}" HorizontalAlignment="Stretch"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding LetterDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}" HorizontalAlignment="Stretch"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<StackPanel Spacing="4">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Students"
|
||||
xmlns:conv="clr-namespace:LehrerApp.Desktop.Converters"
|
||||
x:Class="LehrerApp.Desktop.Views.Students.WebUntisDocumentationComparisonDialog"
|
||||
x:DataType="vm:WebUntisDocumentationComparisonViewModel"
|
||||
Title="Klassenbucheinträge mit WebUntis abgleichen" Width="1150" Height="720"
|
||||
@@ -12,9 +13,9 @@
|
||||
Text="Nur eigene WebUntis-Einträge (Benutzer = eigener Login). Zeilen ohne automatische Zuordnung bitte manuell einem/einer Schüler*in zuweisen. Bereits lokal vorhandene Einträge sind gesperrt."/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="8">
|
||||
<CalendarDatePicker SelectedDate="{Binding StartDate}"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding StartDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}"/>
|
||||
<TextBlock Text="bis" VerticalAlignment="Center"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding EndDate}"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding EndDate, Converter={x:Static conv:DateTimeOffsetToDateTimeConverter.Instance}}"/>
|
||||
<Button Content="Klassenbucheinträge laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user