IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

ValueConverter, méthode ConvertBack non appelée


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut ValueConverter, méthode ConvertBack non appelée
    Bonjour,

    j'ai développé un usercontrol ucTimeRange qui expose une DependencyProperty de type TimeRange.
    J'aimerais binder à cette DependencyProperty une propriété de type string. Ainsi j'aimerais utiliser un IValueConverter pour convertir la propriété de type string en TimeRange et inversement.
    La méthode Convert est appelé lorsque je modifie la valeur de la propriété de type string mais si je sélectionne une autre valeur dans le combo ou saisi une valeur differente dans le textbox, la méthode ConvertBack n'est pas appelé.
    Je ne comprends pas pourquoi.

    Voici la définition du TimeRange:

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class TimeRange
        {
            public TimeFormatEnum Format { get; set; }
     
            public int Value { get; set; }
        }
     
    public enum TimeFormatEnum
        {
            [Description("seconde")]
            s, //seconde
            [Description("minute")]
            m, // minute
            [Description("heure")]
            h, // heure
            [Description("jour")]
            d, // jour
            [Description("semaine")]
            w, // semaine
            [Description("mois")]
            mo, // mois
            [Description("année")]
            y // année
        }

    Voici le code du UserControl:

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <TextBox Name="txtMult" Grid.Column="0" Padding="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" TextAlignment="Right" Text="{Binding ElementName=ucTR, Path=TRange.Value}"/>
            <ComboBox Name="cbTime" Grid.Column="2" Padding="1,0,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
                      ItemsSource="{local:EnumDescriptionsExtension lib:TimeFormatEnum}"
                      DisplayMemberPath="Item2" SelectedValuePath="Item1"
                      SelectedValue="{Binding ElementName=ucTR, Path=TRange.Format,Mode=TwoWay}" />

    Voici le code du TimeRangeConverter:

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    public class TimeRangeConverter : IValueConverter
        {
            public object Convert(object value, Type targetType,
                                  object parameter, System.Globalization.CultureInfo culture)
            {
                if (value == null)
                    return DependencyProperty.UnsetValue;
     
                return ParseTimeRange(value.ToString());
            }
     
            public object ConvertBack(object value, Type targetType,
                                      object parameter, System.Globalization.CultureInfo culture)
            {
                if (value == null)
                    return DependencyProperty.UnsetValue;
     
                TimeRange useValue = (TimeRange)value;
                return useValue.Value.ToString() + useValue.Format.ToString();
            }
     
            private TimeRange ParseTimeRange(string s)
            {
                TimeRange tr = new TimeRange();
     
                if (!string.IsNullOrEmpty(s))
                {
                    // Obtient le code du TimeFormat
                    string codeFormat = new string(s.Where(c => Char.IsLetter(c)).ToArray());
                    // Obtient la valeur du TimeRange
                    int value = 0;
                    if (int.TryParse(s.Replace(codeFormat, ""), out value))
                    {
                        tr.Format = (TimeFormatEnum)Enum.Parse(typeof(TimeFormatEnum), codeFormat);
                        tr.Value = value;
                    }
                }
     
                return tr;
            }
        }

    J'ai bindé ce ValueConverter comme suit:

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    <my:ucTimeRange Grid.Row="0" Grid.Column="2" x:Name="ucTimeRge" HorizontalAlignment="Left" Height="24" Width="181" IsEnabled="{Binding ElementName=rdbRealTime, Path=IsChecked}" TRange="{Binding Path=VTViewModel.RealTimeRange, Converter={StaticResource trConverter}}"/>

    Est-ce que vous auriez une idée ?
    Merci d'avance,
    Zoax.

  2. #2
    Membre Expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Par défaut
    Par défaut pour les dependency properties, le binding est en mode oneway. Mets le explicitement a twoway. A mon avis c'est ça.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Ta propriété VTViewModel.RealTimeRange pourrait pas être directement de type TimeRange ? Il me semble que ce serait plus simple que de passer par un converter...

    Sinon, comme l'a dit GuruuMeditation, c'est simplement une histoire de direction du binding (OneWay/TwoWay). Tu peux spécifier Mode=TwoWay dans le binding, ou alors modifier la déclaration de la dependency property pour que ce soit TwoWay par défaut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public static readonly DependencyProperty TRangeProperty = 
        DependencyProperty.Register(
            "TRange",
            typeof(ucTimeRange),
            typeof(TimeRange),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

  4. #4
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut
    Bonsoir,

    merci pour vos réponses.
    J'ai fait ce que vous avez proposé mais ça ne change rien. Si je sélectionne une autre valeur dans le ComboBox, la méthode ConvertBack n'est pas appelée.

    Ca fait déjà un p'tit moment que je cherche mais pas moyen de trouver le pourquoi.

    Merci d'avance pour votre aide.
    Zoax

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Même en mettant TwoWay = true ? Bizarre... tu as pas de message d'erreur dans la fenêtre de sortie ?

  6. #6
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut
    Citation Envoyé par tomlev
    Même en mettant TwoWay = true ? Bizarre... tu as pas de message d'erreur dans la fenêtre de sortie ?
    Oui en mettant Mode=TwoWay, ça ne fonctionne pas non plus.
    Il n'y a pas de message d'erreur dans la fenêtre de sortie.

    J'ai suivi un des conseils que tu m'as donné précédemment, j'ai bindé une propriété de type TimeRange. Néanmoins j'ai quand même gardé le Converter pour essayer de comprendre:

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    public class TimeRangeConverter : IValueConverter
        {
            public object Convert(object value, Type targetType,
                                  object parameter, System.Globalization.CultureInfo culture)
            {
                if (value == null)
                    return DependencyProperty.UnsetValue;
     
                return value;
            }
     
            public object ConvertBack(object value, Type targetType,
                                      object parameter, System.Globalization.CultureInfo culture)
            {
                if (value == null)
                    return DependencyProperty.UnsetValue;
     
                TimeRange useValue = (TimeRange)value;
                return useValue;
            }
     
            private TimeRange ParseTimeRange(string s)
            {
                TimeRange tr = new TimeRange();
     
                if (!string.IsNullOrEmpty(s))
                {
                    // Obtient le code du TimeFormat
                    string codeFormat = new string(s.Where(c => Char.IsLetter(c)).ToArray());
                    // Obtient la valeur du TimeRange
                    int value = 0;
                    if (int.TryParse(s.Replace(codeFormat, ""), out value))
                    {
                        tr.Format = (TimeFormatEnum)Enum.Parse(typeof(TimeFormatEnum), codeFormat);
                        tr.Value = value;
                    }
                }
     
                return tr;
            }
        }

    Je sais qu'il n'y a pas grand intérêt mais c'est juste pour comprendre. La méthode Convert est bien appelée mais la méthode ConvertBack n'est toujours pas appelée. Et pourtant la propriété bindée est bien mise à jour.
    Quelle est l'explication d'après vous ? Ou ai-je failli ?

    Merci d'avance,
    Zoax

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Portlet] Méthode processAction non-appelée
    Par motorenshi dans le forum Portails
    Réponses: 1
    Dernier message: 22/05/2008, 18h57
  2. "if" d'une méthode non appelé
    Par pikaspike dans le forum Général JavaScript
    Réponses: 31
    Dernier message: 25/04/2008, 10h43
  3. Réponses: 1
    Dernier message: 21/03/2008, 01h51
  4. Réponses: 3
    Dernier message: 23/08/2005, 11h02
  5. [EJB] [JSP] Méthode EJB non reconnue dans jsp
    Par stago dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 06/07/2004, 09h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo