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 :

[WPF][BINDING] Simple normalement, mais là ça ne fonctionne pas.


Sujet :

Windows Presentation Foundation

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut [WPF][BINDING] Simple normalement, mais là ça ne fonctionne pas.
    Bonjour à tous,
    Je rencontre actuellement un petit problème mais je ne vois pas pourquoi!!!
    Une fenêtre avec 1 un usercontrol auquel je voudrais faire passer une valeur.

    Ma fenêtre
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <Window x:Class="Test.Application.GUI.Test2.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:uc="clr-namespace:Test.Application.GUI.Test2"
            Title="Window1" Height="300" Width="300">
        <Grid>
            <StackPanel>
                <TextBox Text="{Binding Path=OneStringValue}" /> // Affiche bien Ceci est un test
                <uc:Uc1 OneString="{Binding Path=OneStringValue}" /> // Erreur de binding 'OneStringValue' property not found (voir plus bas)
            </StackPanel>
        </Grid>
    </Window>

    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
     
    namespace Test.Application.GUI.Test2
    {
        public partial class Window1 : Window
        {
            public struct StructContext{
                public string OneStringValue { get; set; }
            }
     
            public Window1()
            {
                InitializeComponent();
                DataContext = new StructContext(){OneStringValue = "Ceci est un test"};
            }
        }
    }

    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <UserControl x:Class="Test.Application.GUI.Test2.Uc1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <TextBox Text="{Binding Mode=OneWay}" />
        </Grid>
    </UserControl>

    Mon UserControl
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <UserControl x:Class="Test.Application.GUI.Test2.Uc1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <TextBox Text="{Binding Mode=OneWay}" />
        </Grid>
    </UserControl>

    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
     
    namespace Test.Application.GUI.Test2
    {
        public partial class Uc1 : UserControl
        {
            public string OneString{ 
                get{ return (string)GetValue(OneStringProperty); } 
                set{ SetValue(OneStringProperty, value); }
            }
            public static readonly DependencyProperty OneStringProperty = DependencyProperty.Register("OneString", typeof(string), typeof(Uc1), new PropertyMetadata("Not value for string", new PropertyChangedCallback(TextProperty_Changed)));
     
            public Uc1()
            {
                InitializeComponent();
                DataContext = OneString;
            }
     
            private static void TextProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ((Uc1) d).DataContext = e.NewValue.ToString();
            }
        }
    }

    Et voici la fameuse erreur que j'ai

    System.Windows.Data Error: 39 : BindingExpression path error: 'OneStringValue' property not found on 'object' ''String' (HashCode=-140625727)'. BindingExpressionath=OneStringValue; DataItem='String' (HashCode=-140625727); target element is 'Uc1' (Name=''); target property is 'OneString' (type 'String')
    Je en comprend pas pourquoi juste au dessus ça fonctionne et pour le userControl ça ne fonctionne plus.
    Merci d'avance

  2. #2
    Membre habitué
    Inscrit en
    Juin 2008
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 162
    Points : 172
    Points
    172
    Par défaut
    L'erreur est la

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <uc:Uc1 OneString="{Binding Path=OneStringValue}" />
    Vu que le DataContext de ton Uc1 est la chaine de caractères elle même le path Path=OneStringValue ne peut pas être resolu.

    Il faut donc faire :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    <uc:Uc1 OneString="{Binding Path=OneStringValue}" />

    Il y a une autre erreur

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public Uc1()
    {
     InitializeComponent();
     DataContext = OneString;
    }

    Le DataContext de UC1 ne vas jamais être modifié après. quand OneString changera. Le mieux est de garder le DataContext par defaut et de faire un binding du genre:

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <UserControl x:Class="Test.Application.GUI.Test2.Uc1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <TextBox Text="{Binding OneString, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=OneWay}" />
        </Grid>
    </UserControl>

  3. #3
    Membre habitué
    Inscrit en
    Juin 2008
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 162
    Points : 172
    Points
    172
    Par défaut
    En fait l'erreur elle est surtout ici:

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    private static void TextProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ((Uc1) d).DataContext = e.NewValue.ToString();
            }

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut
    Merci pour t'être penché sur mon problème.
    Par contre pour ête honnête je n'ai pas tout compris.
    Il faut donc faire :
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <uc:Uc1 OneString="{Binding Path=OneStringValue}" />
    Mais c'est déjà ce que j'avais non????


    Pour le reste si j'ai bien compris.
    1) Je ne défini pas de datacontext dans mon UserControl
    2) Je me binde directement sur l'attribut OneString de mon UserControl en faisant:
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <TextBox Text="{Binding OneString, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=OneWay}" />
    => il cherche OneString dans l'ancètre de type UserControl, donc lui même, c'est bien ça?

  5. #5
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Salut,

    Si tu mets à jour ton binding dans ton event TextProperty_Changed, ça devrait le faire :
    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
    namespace Test.Application.GUI.Test2
    {
        public partial class Uc1 : UserControl
        {
            public string OneString{ 
                get{ return (string)GetValue(OneStringProperty); } 
                set{ SetValue(OneStringProperty, value); }
            }
            public static readonly DependencyProperty OneStringProperty = DependencyProperty.Register("OneString", typeof(string), typeof(Uc1), new PropertyMetadata("Not value for string", new PropertyChangedCallback(TextProperty_Changed)));
     
            public Uc1()
            {
                InitializeComponent();
            }
     
            private static void TextProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                Uc1 ctrl = d as Uc1;
                if (ctrl != null) {
                  string val = e.NewValue as string;
     
                  if (val != null)
                    ctrl.DataContext = val;
              }
            }
     
        }
    }

    Ceci avec le même code xaml que tu avais présenté dans ton premier post.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut
    @binoo
    Citation Envoyé par binoo Voir le message
    Salut,
    Si tu mets à jour ton binding dans ton event TextProperty_Changed, ça devrait le faire :
    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
    namespace Test.Application.GUI.Test2
    {
        public partial class Uc1 : UserControl
        {
            public string OneString{ 
                get{ return (string)GetValue(OneStringProperty); } 
                set{ SetValue(OneStringProperty, value); }
            }
            public static readonly DependencyProperty OneStringProperty = DependencyProperty.Register("OneString", typeof(string), typeof(Uc1), new PropertyMetadata("Not value for string", new PropertyChangedCallback(TextProperty_Changed)));
     
            public Uc1()
            {
                InitializeComponent();
            }
     
            private static void TextProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                Uc1 ctrl = d as Uc1;
                if (ctrl != null) {
                  string val = e.NewValue as string;
     
                  if (val != null)
                    ctrl.DataContext = val;
              }
            }
     
        }
    }

    Ceci avec le même code xaml que tu avais présenté dans ton premier post.
    ==> j'ai la même erreur de binding
    System.Windows.Data Error: 39 : BindingExpression path error: 'OneStringValue' property not found on 'object' ''String' (HashCode=-140625727)'. BindingExpressionath=OneStringValue; DataItem='String' (HashCode=-140625727); target element is 'Uc1' (Name=''); target property is 'OneString' (type 'String')

    @goast
    Je viens de faire la chose suivante:
    Windows1
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <Window x:Class="Test.Application.GUI.Test2.T2.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:uc="clr-namespace:Test.Application.GUI.Test2.T2"
            Title="Window1" Height="300" Width="300">
        <Grid>
            <StackPanel>
                <TextBox Text="{Binding Path=OneStringValue}" />
                <uc:Uc1 OneString="{Binding Path=OneStringValue}" />
                <uc:Uc2 OneString="{Binding Path=OneStringValue}" />
            </StackPanel>
        </Grid>
    </Window>

    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
     
    namespace Test.Application.GUI.Test2.T2
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public struct StructContext{
                public string OneStringValue { get; set; }
            }
     
            public Window1()
            {
                InitializeComponent();
                DataContext = new StructContext(){OneStringValue = "Ceci est un test"};
            }
        }
    }

    UC1
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <UserControl x:Class="Test.Application.GUI.Test2.T2.Uc1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <TextBox Text="{Binding Path=OneString, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
        </Grid>
    </UserControl>

    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
     
    namespace Test.Application.GUI.Test2.T2
    {
        /// <summary>
        /// Interaction logic for Uc1.xaml
        /// </summary>
        public partial class Uc1 : UserControl
        {
            public string OneString{ 
                get{ return (string)GetValue(OneStringProperty); } 
                set{ SetValue(OneStringProperty, value); }
            }
            public static readonly DependencyProperty OneStringProperty = DependencyProperty.Register("OneString", typeof(string), typeof(Uc1), new PropertyMetadata("Not value for string"));
     
            public Uc1()
            {
                InitializeComponent();
            }
        }
    }

    IDEM pour UC2

    Je n'ai pas d'erreur de binding, mais quand je modifie la valeur d'un, ça ne modifie pas la valeur des autres.

  7. #7
    Membre habitué
    Inscrit en
    Juin 2008
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 162
    Points : 172
    Points
    172
    Par défaut
    Desolé c'etait une erreur de copier coller. Je voulais dire qu'il fallait faire ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <uc:Uc1 OneString="{Binding}" />
    Pour pouvoir modifier la valeur de la proprieté sur la quel est bindé ton TextBlock il faut que le binding soit en Mode=TwoWay. Donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <uc:Uc1 OneString="{Binding Path=OneStringValue, Mode=TwoWay}" />
    Mais aussi:
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    <TextBox Text="{Binding Path=OneString, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />

    Mais attention par défaut la valeur est mise à jour lors qu'on appuis sur la touche entré ou Tab. Si non il faut modifier le mode de mise à jour du binding.

Discussions similaires

  1. Réponses: 4
    Dernier message: 20/09/2011, 00h04
  2. Réponses: 2
    Dernier message: 14/04/2009, 12h27
  3. 2 requêtes identiques mais l'une ne fonctionne pas
    Par bybelos33 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 27/03/2009, 09h06
  4. [AJAX] simple affichage avec Ajax.Request ne fonctionne pas
    Par karimphp dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 18/12/2007, 09h35
  5. Réponses: 8
    Dernier message: 15/09/2006, 19h37

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