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

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    juillet 2008
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2008
    Messages : 1 448
    Points : 1 275
    Points
    1 275

    Par défaut [Binding] sur une propriété indirecte

    bonjour
    j'aimerais faire un binding indirect (sans passer par refaire un markup qui s'occuperait du travail)
    donc : imaginons que j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public string REF { get; set; } = "ZOZO";
    public string ZOZO { get; set; } = "il est beau le temps qui passe doucement";
    et que je veuille faire un binding sur un textblock
    pour avoir a partir de la valeur de REF un binding sur ce que contient REF donc sur ZOZO
    un peut comme le DisplayMemberBinding de la GridviewColumn

    si quelqu'un a une idée
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!

  2. #2
    Membre averti Avatar de WaterTwelve21
    Homme Profil pro
    Développeur .NET
    Inscrit en
    décembre 2015
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : décembre 2015
    Messages : 258
    Points : 443
    Points
    443

    Par défaut

    J'ai pas compris ...

    Tu veux un Binding sans faire ={Binding ... } ?

    On peut avoir un peu plus de précision ?
    throw new NoSignatureException();

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    juillet 2008
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2008
    Messages : 1 448
    Points : 1 275
    Points
    1 275

    Par défaut

    je te ré-explique ce que je veux faire
    je veux tenter le même mécanisme que displaymemberbinding

    je crée un customcontrol avec un memberbinding="Alpha"
    et ce que je veux c'est qu'a l’intérieur du generic.xaml
    tu ai par exemple
    <textblock text={binding Alpha}" />

    si j'avais mis memberbinding="Beta"
    ça aurait donné ça
    <textblock text={binding Beta}" />

    c'est une sorte de binding indirect

    ce qui me permet de faire un binding sur un membre du datacontext en précisant le nom de ce membre
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    juillet 2008
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2008
    Messages : 1 448
    Points : 1 275
    Points
    1 275

    Par défaut

    bon j'ai fait un truc avec un markup
    si vous pouviez me dire si le code est plutot correct

    markup
    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
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
       [MarkupExtensionReturnType(typeof(object))]
        public class Reference : MarkupExtension
        {
            private object _key = null;
     
            #region Constructors
            public Reference() { }
            public Reference(object key) { _key = key; }
            #endregion
     
            #region Key for binding (ATTACHED) (KeyBindingProperty & KeyBindingInfoProperty)
     
            private static DependencyProperty KeyBindingInfoProperty = DependencyProperty.RegisterAttached(
              "KeyBindingInfo",
              typeof(object),
              typeof(Reference),
              new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
     
            private static DependencyProperty FirstKeyBindingProperty = DependencyProperty.RegisterAttached(
               "FirstKeyBinding",
               typeof(object),
               typeof(Reference),
               new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, FirstChange));
     
            private static void FirstChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                try
                {
                    DependencyObject _targetObject = d;
                    DependencyProperty _targetProperty = _targetObject.GetValue(Reference.KeyBindingInfoProperty) as DependencyProperty;
                    object value = _targetObject.GetValue(Reference.FirstKeyBindingProperty);
                    // reset binding to reference value
                    Binding binding = new Binding((string)value);
                    BindingOperations.SetBinding(_targetObject, Reference.KeyBindingProperty, binding);
                }
                catch { }
            }
     
            private static DependencyProperty KeyBindingProperty = DependencyProperty.RegisterAttached(
                "KeyBinding",
                typeof(object),
                typeof(Reference),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, Change));
     
            private static void Change(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                try
                {
                    DependencyObject _targetObject = d;
                    DependencyProperty _targetProperty = _targetObject.GetValue(Reference.KeyBindingInfoProperty) as DependencyProperty;
                    object value = _targetObject.GetValue(Reference.KeyBindingProperty);
                    _targetObject.SetValue(_targetProperty, value);
                }
                catch { }
            }
            #endregion
     
            public override object ProvideValue(IServiceProvider serviceProvider)
            {
                DependencyObject _targetObject = null;
                DependencyProperty _targetProperty = null;
                if (_key is Binding)
                {
                    Binding binding = _key as Binding;
                    IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
                    if (target != null &&
                        target.TargetObject is DependencyObject &&
                        target.TargetProperty is DependencyProperty)
                    {
                        _targetObject = (DependencyObject)target.TargetObject;
                        _targetProperty = (DependencyProperty)target.TargetProperty;
                    }
                    else
                    {
                        return this; // magic
                    }
                    // cette ligne doit etre positionné avant le set du binding sinon le binding se realise et on ne retrouve pas _targetProperty
                    _targetObject.SetValue(Reference.KeyBindingInfoProperty, _targetProperty);
                    BindingOperations.SetBinding(_targetObject, Reference.FirstKeyBindingProperty, binding);
                    object value = _targetObject.GetValue(Reference.FirstKeyBindingProperty);
                    if(value == null)
                    {
                        var meta = _targetProperty.GetMetadata(_targetObject);
                        value = meta.DefaultValue;
                    }
                    return value;
                }
                else
                {
                    try
                    {
                        IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
                        if (target != null &&
                            target.TargetObject is DependencyObject &&
                            target.TargetProperty is DependencyProperty)
                        {
                            _targetObject = (DependencyObject)target.TargetObject;
                            _targetProperty = (DependencyProperty)target.TargetProperty;
                        }
                        Binding binding = new Binding((string)_key);
                        _targetObject.SetValue(Reference.KeyBindingInfoProperty, _targetProperty);
                        BindingOperations.SetBinding(_targetObject, Reference.KeyBindingProperty, binding);
                        return _targetObject.GetValue(Reference.KeyBindingProperty);
                    }
                    catch { return null; }
                }
                throw new InvalidOperationException("Inputs cannot be blank");
            }
        }
    exemple de code xaml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          <TextBlock Margin="0 10 0 0"
                       Background="LightCoral"
                       DockPanel.Dock="Top"
                       Text="{local:Reference {Binding Gamma, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}}" />
    code dans la fenetre
    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
     #region  Alpha
            private string _Alpha = "valeur pour alpha";
            public string Alpha
            {
                get { return _Alpha; }
                set { _Alpha = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Alpha")); }
            }
            #endregion
     
            #region  Beta
            private string _Beta = "Valeur pour beta";
            public string Beta
            {
                get { return _Beta; }
                set { _Beta = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Beta")); }
            }
            #endregion
     
            #region  Gamma
            private string _Gamma = "Beta";
            public string Gamma
            {
                get { return _Gamma; }
                set { _Gamma = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Gamma")); }
            }
            #endregion
    le code ne prend pas forcement en compte le changement de la valeur de Gamma (enfin pour le moment)
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!

  5. #5
    Membre expert
    Inscrit en
    avril 2008
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 59

    Informations forums :
    Inscription : avril 2008
    Messages : 2 155
    Points : 3 679
    Points
    3 679

    Par défaut

    bonjour

    DisplayMemberBinding est une prop CLR de type BindingBase ...
    Son role est donc de "copier" ou cloner carrément un Binding et de l'affecter à un control 'CTL" situe dans le fichier "generic.xaml" pourvu d'un nom qui obéit aux règles d'identification des Templates Parts...

    Par suite le 'CTL" doit être "bindé" à cette "copie" dans la méthode OnApplyTemplate() qu'il convient d'overrider....
    exemple code

    1/code .cs du custom control:
    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
     
    namespace WpDisplayIkeas
    {
        [TemplatePart(Name = "PART_TB", Type = typeof(FrameworkElement))]
        public class MyContro1 : Control
        {
            TextBlock tb = null;
            static MyContro1()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(MyContro1), new FrameworkPropertyMetadata(typeof(MyContro1)));
            }
     
            public BindingBase DisplayMemberBinding { get; set; }
     
            public override void OnApplyTemplate()
            {
                base.OnApplyTemplate();
                tb = Template.FindName("PART_TB", this) as TextBlock;
                if (this.DisplayMemberBinding  != null)
                {
                    tb.SetBinding(TextBlock.TextProperty, this.DisplayMemberBinding);
                }
     
            }
        }
    }
    fichier "generic.xam" du custom control:
    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
     
    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpDisplayIkeas">
     
     
        <Style TargetType="{x:Type local:MyContro1}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:MyContro1}">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                            <TextBlock 
                                Name="PART_TB" 
                                FontFamily="Times New Roman"
                                FontSize="24"
                                Foreground="Red" 
                                Text="{Binding  }"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
    code xaml de la fenetre user:

    Code : 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="WpDisplayIkeas.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpDisplayIkeas" 
            Title="MainWindow" Height="350" Width="525">
        <StackPanel >
            <TextBox x:Name="txt" Text="Ola ,Ole IKEAS"/>
            <local:MyContro1
                DisplayMemberBinding="{Binding ElementName=txt,Path=Text}"
                >
            </local:MyContro1>
        </StackPanel>
    </Window>
    bon code...

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    juillet 2008
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2008
    Messages : 1 448
    Points : 1 275
    Points
    1 275

    Par défaut

    mais sinon tu pense quoi de mon code ?
    en sachant que j'ai un custom control
    et que je realise le binding dans le style sur la dp du customcontrol

    comme ceci
    <moncustomcontrol memeberbinding={binding Alpha} />

    donc le rmarkup est utilisé dans le style
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!

Discussions similaires

  1. Binding sur une proprité d'une propriété
    Par al2000 dans le forum Windows Forms
    Réponses: 0
    Dernier message: 21/06/2010, 17h24
  2. Binding sur une propriété
    Par Villard.patrick dans le forum Silverlight
    Réponses: 5
    Dernier message: 09/12/2009, 17h52
  3. binding sur une propriété shared (vb) static (c#) ?
    Par Pol63 dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 24/06/2009, 15h44
  4. Binding sur une propriété avec paramètre
    Par FRED.G dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 17/11/2008, 18h38
  5. [Databinding] bind sur une propriété d'une collection
    Par herveb dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 11/12/2007, 10h35

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