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 :

Binder un Binding


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut Binder un Binding
    Bonjour,

    je développe un petit composant qui est grosso modo une TextBox wrappée dans une Border et accolée à une Image;
    la Border et l'Image changeant en fonction de l'état de validation du contenu de la TextBox.

    Cependant je voudrais que l'utilisateur puisse passer en propriété du composant un objet Binding sur lequel se basera la validation.
    Autant passer un objet de type string ne pose aucun problème autant un objet Binding semble être interprété par WPF et ne pas être transmis comme un vrai objet au composant.

    Voilà le code du composant :
    Le XAML :
    Code : 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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    <UserControl
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="Test.ValidationTextBox"
        x:Name="Self"
     
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     
        xmlns:Test="clr-namespace:Test"
    >
        <UserControl.Resources>
            <Test:IsNullOrEmptyTester x:Key="IsNullOrEmptyTester" />
        </UserControl.Resources>
     
        <StackPanel Orientation="Horizontal">
            <Border Name="TextBoxBorder" BorderThickness="1" Width="{Binding ElementName=TextBox,Path=Width}" HorizontalAlignment="Left">
                <Border.Style>
                    <Style TargetType="Border">
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=TextBox,Path=(Validation.HasError)}" Value="True" />
                                    <Condition Binding="{Binding ElementName=TextBox,Path=Text,Converter={StaticResource IsNullOrEmptyTester}}" Value="False" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="BorderBrush" Value="Red" />
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=TextBox,Path=(Validation.HasError)}" Value="False" />
                                    <Condition Binding="{Binding ElementName=TextBox,Path=Text,Converter={StaticResource IsNullOrEmptyTester}}" Value="False" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="BorderBrush" Value="Green" />
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
                <TextBox
                        Name="TextBox"
                        Width="100"
                        MaxLength="10"
                        Validation.ErrorTemplate="{x:Null}"
                    >
     
                    <TextBox.Style>
     
                        <Style TargetType="TextBox">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.HasError)}" Value="True">
                                    <Setter Property="ToolTip"
                                                Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.Errors)[0].ErrorContent}"
                                        />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.HasError)}" Value="False">
                                    <Setter Property="ToolTip" Value="{Binding ElementName=Self,Path=DefaultToolTipText}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
     
                    </TextBox.Style>
     
                </TextBox>
            </Border>
     
            <Image>
                <Image.Style>
                    <Style TargetType="Image">
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=TextBox,Path=(Validation.HasError)}" Value="True" />
                                    <Condition Binding="{Binding ElementName=TextBox,Path=Text,Converter={StaticResource IsNullOrEmptyTester}}" Value="False" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Source" Value="/media/images/error.png" />
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=TextBox,Path=(Validation.HasError)}" Value="False" />
                                    <Condition Binding="{Binding ElementName=TextBox,Path=Text,Converter={StaticResource IsNullOrEmptyTester}}" Value="False" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Source" Value="/media/images/noError.png" />
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </Image.Style>
            </Image>
        </StackPanel>
    </UserControl>
    Le code-behind :
    Code : 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
    42
    43
    44
    45
    46
    47
    48
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
     
    namespace Test
    {
        /// <summary>
        /// Interaction logic for ValidationTextBox.xaml
        /// </summary>
        public partial class ValidationTextBox : UserControl
        {
            public static readonly DependencyProperty BindingProperty
                = DependencyProperty.Register("Binding", typeof(Binding), typeof(ValidationTextBox));
     
            public Binding Binding
            {
                get
                {
                    return (Binding)this.GetValue(BindingProperty);
                }
                set
                {
                    this.SetValue(BindingProperty, value);
                    this.TextBox.SetBinding(TextBox.TextProperty, value);
                }
            }
     
            public static readonly DependencyProperty DefaultToolTipTextProperty
                = DependencyProperty.Register("DefaultToolTipText", typeof(string), typeof(ValidationTextBox));
     
            public string DefaultToolTipText
            {
                get
                {
                    return (string)this.GetValue(DefaultToolTipTextProperty);
                }
                set
                {
                    this.SetValue(DefaultToolTipTextProperty, value);
                }
            }
     
            public ValidationTextBox()
            {
                InitializeComponent();
            }
        }
    }
    Et une tentative d'utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <test:ValidationTextBox Grid.Row="3" Grid.Column="1" DefaultToolTipText="Test" Binding="{DynamicResource DateBinding}">
    	<test:ValidationTextBox.Binding>
    		<Binding Path="Date" UpdateSourceTrigger="PropertyChanged">
    			<Binding.ValidationRules>
    				<test:ISODateFormatRule />
    			</Binding.ValidationRules>
    			<Binding.Converter>
    				<test:DateTimeConverter />
    			</Binding.Converter>
    		</Binding>
    	</test:ValidationTextBox.Binding>
    </test:ValidationTextBox>
    Le composant se comporte bien quand la TextBox est vide : il n'y a ni bordure ni image, mais s'il y a des données, quelles qu'elles soient, la Border est verte et l'Image celle de la validation passée.
    Le débuggage avec VS2008 montre bien que le Binding n'est pas utilisé : ni le IValueConverter ni la ValidationRule ne sont invoqués.


    1) Quelle est la source du problème ?
    2) Comment y remédier et transmettre tel quel le Binding ?



    Merci d'avance.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Par défaut
    t'aurais pas un projet exemple ?

  3. #3
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Pas compris ton pb.....

  4. #4
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Merci de vous pencher sur le problème.
    Désolé de ne pas avoir été plus explicite; j'ai joint un projet VS2008 de démo.

    Sinon une autre solution serait de faire dériver le composant de TextBox et de binder une nouvelle propriété de dépendance Text sur la propriété Text de la TextBox sous-jacente.
    Mais tant qu'à faire cela il serait bien de binder toutes les propriétés héritées vers celles de la TextBox sous-jacente afin que tout se passe comme si l'utilisateur utilisait une vraie TextBox.

    Connaissez-vous une manière de procéder ?


    Merci.

  5. #5
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Bon finalement j'ai implémenté la solution présentée dans le message précédent.
    Le tout est dans le projet VS2008 joint.

    Le problème reste le binding des autres propriétés que Text : pour MaxLength par exemple il suffit de la placer sur la TextBox sous-jacente comme cela a été fait.
    Mais pour Width par exemple c'est plus problématique : elle ne peut être affectée à Width de la TextBox sous-jacente car sinon elle prend toute la place et cache l'image.
    Si elle est bindée au niveau de la propriété Width du StackPanel la TextBox prend sa largeur minimale.

    Quelle est la bonne façon de répercuter la propriété Width indiquée par l'utilisateur sur la ValidationTextBox sur les autres composants afin que la largeur totale de la ValidationTextBox soit bien Width et que la largeur de la TextBox sous-jacente soit maximum sans cacher l'image ?

    Merci.


    PS : J'ai retiré le projet joint au message précédent car il n'est plus pertinent.
    Fichiers attachés Fichiers attachés

  6. #6
    Membre chevronné Avatar de MetalGeek
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 412
    Par défaut
    Salut,
    pour Width ça le ferait peut-être mieux une Grid à la place du StackPanel, en jouant ensuite avec les propriétés HorizontalAlignment du contenu (à Stretch pour la TextBox) et/ou les propriétés Width des ColumnDefinitions de la Grid.

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 26/09/2010, 11h02
  2. [Binding] Comment binder 2 sources sur un seul Control ?
    Par adrienfehr dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 26/09/2008, 22h18
  3. [bind] Binder plusieurs services
    Par V_R46 dans le forum Réseau
    Réponses: 1
    Dernier message: 04/09/2008, 10h54
  4. [WPF][Binding] Comment binder un fichier XML sur un treeview?
    Par bakonu dans le forum Général Dotnet
    Réponses: 5
    Dernier message: 26/11/2007, 17h09
  5. Bind - sous-domaine
    Par _Gabriel_ dans le forum Réseau
    Réponses: 4
    Dernier message: 07/03/2004, 11h54

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