none
UWP : ListView : Affichage par défaut dans un CalendarDatePicker RRS feed

  • Question

  • Bonjour,

    Dans mon application UWP sous Windows 10 build 18362, j’ai une ListView qui contient un CalendarDatePicker. La valeur affichée dans le champ de ce contrôle est stockée dans une base SQLite au format texte. Après lecture de ce champ texte (format yyyyMMdd), je le convertis au format DateTimeOffset avec un Converter, et cela  fonctionne très bien.

    Mon problème survient quand le champ date est null (l’utilisateur n’a pas choisi de date dans le CalendarDatePicker avant d’enregistrer ses données). Ensuite, à l’ouverture de la page, le CalendarDatePicker affiche toujours une date par défaut qui est 01/01/1919, alors qu’il devrait me proposer le PlaceholderText défini.

    Voici des extraits du code XAML de la page:

    <ListView x:Name="listVProjets"
                          Margin="0,140,0,40"
                          IsItemClickEnabled="True" 
                          ItemClick="ListVProjets_ItemClick"
                          SelectionChanged="ListVProjets_SelectionChanged"
                          >
    
    
                    <ListView.ItemTemplate>
                        <DataTemplate x:DataType="local1:Projets">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="40" />
                                    <ColumnDefinition Width="40" />
                                    <ColumnDefinition Width="240" />
                                    <ColumnDefinition Width="150" />
                                    <ColumnDefinition Width="150" />
                                    <ColumnDefinition Width="110" />
                                    <ColumnDefinition Width="110" />
                                </Grid.ColumnDefinitions>
    
                                <Button     Grid.Column="0"
                                            x:Name="btnOpenSProj"
                                            Content="--"
                                            Tag="{Binding}"
                                            Click="BtnOpenSProj_Click"/>
                                <CheckBox   Grid.Column="1"
                                            x:Name="chkBoxProj"
                                            Margin="15,0,0,0"
                                            Tag="{Binding}"
                                            Click="ChkBoxProj_Click"
                                            IsChecked="{Binding IsChk, Converter={StaticResource NullableBooleanToBooleanConverter}, Mode=OneWay}"/>
                                <TextBox Grid.Column="2" 
                                           x:Name="nomProjTxt"
                                           Margin="20,0,0,0" 
                                           TextWrapping="NoWrap" 
                                           BorderBrush="Transparent"
                                           Text="{Binding NomProj, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                           FontSize="16" 
                                           Foreground="Black"
                                           PlaceholderText="Nom du projet"
                                           SelectionChanged="NomProjTxt_SelectionChanged"/>
                                
                                <CalendarDatePicker Grid.Column="3" 
                                           Name="dateprojPTxt"
                                           Margin="20,0,0,0" 
                                           BorderBrush="Transparent"
                                           FontSize="16" 
                                           Foreground="Black"
                                           IsTodayHighlighted="True"
                                           DateChanged="DateprojPTxt_DateChanged"
                                           Tag="{Binding}"
                                           Date="{x:Bind DateProjPrevu, Converter={StaticResource StringToDateTimeOffsetConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  DateFormat="{}{day.integer(2)}/{month.integer(2)}/{year.full}"
                                           />

    Et le code behind du converter :

    public class StringToDateTimeOffsetConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, string language)
            {
                DateTimeOffset dt;
                if (value != null && value is string)
                {
                    var stringToConvert = value as string;
                    if (!DateTimeOffset.TryParse(stringToConvert, out dt))
                    {
                        return null;
                    }
                }
                return dt;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, string language)
            {
                string time;
                if (value != null && value is DateTimeOffset)
                {
                    var valueToConvert = (DateTimeOffset)value;
                    time = new DateTime(valueToConvert.Ticks).ToString("yyyyMMdd");
                }
                else
                {
                    time = string.Empty;
                }
                return time;
            }
        }

    Toute aide sera bienvenue. Merci.

    mardi 10 septembre 2019 14:12

Réponses

  • La réponse m’a été donnée par Faywang – MSFT : le problème se trouvait dans le Converter.

    Quand le champ date est null, le Converter ne renvoie PAS une valeur nulle, mais la valeur de dt (01/01/0001 00:00 :00 +00:00), que le bind transforme en 01/01/1919).

    J’ai modifié le Converter comme il me l’a dit :

    public class StringToDateTimeOffsetConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, string language)
            {
                DateTimeOffset dt;
                if (value != null && value is string)
                {
                    var stringToConvert = value as string;
                    if (!DateTimeOffset.TryParse(stringToConvert, out dt))
                    {
                        return null;
                    }
                }
                else if (value == null)
                {
                    return null;
                }
                return dt;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, string language)
            {
                string time;
                if (value != null && value is DateTimeOffset)
                {
                    var valueToConvert = (DateTimeOffset)value;
                    time = new DateTime(valueToConvert.Ticks).ToString("yyyyMMdd");
                }
                else
                {
                    time = null;
                }
                return time;
            }
        }

    Et cela fonctionne parfaitement. Merci à tous, et surtout à Faywang.


    • Marqué comme réponse Mani035 mercredi 11 septembre 2019 17:55
    • Modifié Mani035 mercredi 11 septembre 2019 17:56
    mercredi 11 septembre 2019 17:54

Toutes les réponses

  • Bonjour Mani035,

    Il y a quelques idées dans le thread suivant:
    How to convert to DateTime but have default value if input is blank?

    Cordialement, 
    Nina

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    mercredi 11 septembre 2019 11:43
    Modérateur
  • Bonjour Nina,

    Merci pour ce conseil. J'ai bien examiné toutes les réponses, mais mon problème n'est pas exactement celui-là.

    En effet, si la valeur de la date est nulle, je n'ai pas d'erreur générée par le binding, mais au lieu d'un champ vide (ou d'un placeholdertext), le Calendardatepicker affiche toujours une date (01/01/1919), qui correspond à l'année en cours - 100. Ce problème est bien décrit ici.

    Malheureusement, les solutions proposées ne fonctionnent pas (en ce qui me concerne). Est-ce un problème reconnu par Microsoft ?

    Je continue mes recherches et ne manquerai pas de poster la solution, si je la trouve !

    mercredi 11 septembre 2019 17:15
  • La réponse m’a été donnée par Faywang – MSFT : le problème se trouvait dans le Converter.

    Quand le champ date est null, le Converter ne renvoie PAS une valeur nulle, mais la valeur de dt (01/01/0001 00:00 :00 +00:00), que le bind transforme en 01/01/1919).

    J’ai modifié le Converter comme il me l’a dit :

    public class StringToDateTimeOffsetConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, string language)
            {
                DateTimeOffset dt;
                if (value != null && value is string)
                {
                    var stringToConvert = value as string;
                    if (!DateTimeOffset.TryParse(stringToConvert, out dt))
                    {
                        return null;
                    }
                }
                else if (value == null)
                {
                    return null;
                }
                return dt;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, string language)
            {
                string time;
                if (value != null && value is DateTimeOffset)
                {
                    var valueToConvert = (DateTimeOffset)value;
                    time = new DateTime(valueToConvert.Ticks).ToString("yyyyMMdd");
                }
                else
                {
                    time = null;
                }
                return time;
            }
        }

    Et cela fonctionne parfaitement. Merci à tous, et surtout à Faywang.


    • Marqué comme réponse Mani035 mercredi 11 septembre 2019 17:55
    • Modifié Mani035 mercredi 11 septembre 2019 17:56
    mercredi 11 septembre 2019 17:54