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 :

[Binding] sur une propriété indirecte


Sujet :

Windows Presentation Foundation

  1. #1
    Membre expérimenté
    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
    Points : 1 313
    Points
    1 313
    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 !!!!
    http://ultimatecorp.eu/wpf/

  2. #2
    Membre confirmé Avatar de WaterTwelve21
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2015
    Messages
    270
    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 : 270
    Points : 461
    Points
    461
    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 expérimenté
    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
    Points : 1 313
    Points
    1 313
    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
    Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
    <textblock text={binding Alpha}" />

    si j'avais mis memberbinding="Beta", ça aurait donné ça
    Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
    <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 !!!!
    http://ultimatecorp.eu/wpf/

  4. #4
    Membre expérimenté
    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
    Points : 1 313
    Points
    1 313
    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 XAML : 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 !!!!
    http://ultimatecorp.eu/wpf/

  5. #5
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    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
    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 XAML : 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
    <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 fenêtre user:

    Code XAML : 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="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 expérimenté
    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
    Points : 1 313
    Points
    1 313
    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
    Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
    <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 !!!!
    http://ultimatecorp.eu/wpf/

  7. #7
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    rebonjour

    Ton code qui n'est guere comprehensible que par son auteur...
    Quant au probleme posé il n'est soluble par un MarkupExtension celui ne pouvant modifier un binding en cours...
    Le seul moyen c'est un class intermédiaire qui va servir de "property watcher" (une version custom de TypeDescriptor.AddValueChanged)
    Il va surveiller la valeur de la prop REF ...c.à.d espionner tout "Binding posé sur elle" et utiliser la "Reflection" (qui est une "flexion") pour procéder à une subversion ou coup d’État contre le Binding en cours......... en le changeant !!!

    TypeDescriptor n’étant pas utilisable en l’état car c'est un class static qui doit ajouter un Handler pour AddValueChanged ,Handler qui ne peut être supprimé d'ou un problème de "weak reference" ,donc des fuites mémoire...

    code behind.cs du class "property watcher":
    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
    namespace WpfWatcherDP
    {
        public class DPWatcher<T> : DependencyObject, IDisposable
        {
            public event EventHandler PropertyChanged;
     
            public DPWatcher(DependencyObject target, string propertyPath)
            {
                this.Target = target;
                Binding bd = new Binding()
                {
                    Source = target,
                    Path = new PropertyPath(propertyPath),
                    Mode = BindingMode.OneWay
                };
                BindingOperations.SetBinding(
                    this,
                    ValueProperty,
                    bd);
            }
            public DependencyObject Target { get; private set; }
     
            public T Value
            {
                get { return (T)this.GetValue(ValueProperty); }
            }
     
     
            public static readonly DependencyProperty ValueProperty =
                DependencyProperty.Register(
                    "Value",
                    typeof(object),
                    typeof(DPWatcher<T>),
                    new PropertyMetadata(null, OnPropertyChanged));
            public static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs args)
            {
                DPWatcher<T> source = (DPWatcher<T>)sender;
     
                if (source.PropertyChanged != null)
                {
                    source.PropertyChanged(source, EventArgs.Empty);
                }
            }
     
            public void Dispose()
            {
                this.ClearValue(ValueProperty);
            }
        }
    }
    Exemple 1 sur un UserControl:
    Code XAML : 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
    <UserControl x:Class="WpfWatcherDP.UserControl1"
                 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>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <DockPanel Grid.Row="0">
                <Label 
                    Content="Gamma "
                    MinWidth="50"/>
                <TextBlock 
                VerticalAlignment ="Center"
                Text="{Binding Gamma,RelativeSource={
                RelativeSource 
                Mode=FindAncestor,AncestorType={x:Type UserControl}}}"/>
            </DockPanel>
            <DockPanel Grid.Row="1">
                <Label 
                    Content="Alpha "
                    MinWidth="50"/>
                <TextBlock  
                VerticalAlignment ="Center"
                Text="{Binding Alpha,RelativeSource={
                RelativeSource 
                Mode=FindAncestor,AncestorType={x:Type UserControl}}}"/>
            </DockPanel>
            <DockPanel Grid.Row="2">
                <Label 
                    Content="Beta"
                    MinWidth="50"/>
                <TextBlock 
                VerticalAlignment ="Center"
                Text="{Binding Beta,RelativeSource={
                RelativeSource 
                Mode=FindAncestor,AncestorType={x:Type UserControl}}}"/>
            </DockPanel>
        </Grid>
    </UserControl>
    et son code behind.cs:
    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
    namespace WpfWatcherDP
    {
        /// <summary>
        /// Logique d'interaction pour UserControl1.xaml
        /// </summary>
        public partial class UserControl1 : UserControl, INotifyPropertyChanged
        {
     
            private DPWatcher<string> watcher; 
            public UserControl1()
            {
                InitializeComponent();
            }
     
            #region Alpha
            private string _alpha = "valeur pour alpha";
            public string Alpha
            {
                get { return _alpha; }
                set
                {
                    if (_alpha != value)
                    {
                        _alpha = value;
                        Raise("Alpha");
                    } 
                }
            }
            #endregion
     
            #region  Beta
            private string _beta = "Valeur pour beta";
            public string Beta
            {
                get { return _beta; }
                set 
                {
     
                    if (_beta != value)
                    {
                        _beta = value;
                        Raise("Beta"); 
                    } 
     
                }
            }
            #endregion
     
            #region  Gamma
            private string _gamma ;
            public string Gamma
            {
                get { return _gamma; }
                set
                {
                    if( _gamma != value)
                    {
                        _gamma = value;
                        this.watcher =
                        new DPWatcher<string>(this,  "Gamma");
                        this.watcher.PropertyChanged += new EventHandler(watcher_PropertyChanged);
                        Raise("Gamma");
                    } 
     
                }
            }
     
            private void watcher_PropertyChanged(object sender, EventArgs e)
            {
                DPWatcher<string> currentWatcher = (DPWatcher<string>)sender;
                var text = currentWatcher.Value;
     
                UserControl1 ctl = currentWatcher.Target as UserControl1;
                PropertyInfo[] pinfos = typeof(UserControl1).GetProperties();
                PropertyInfo pinfoGamma = Array.Find(pinfos, (o => o.Name == "Gamma"));
                PropertyInfo pinfoAlpha = Array.Find(pinfos, (o => o.Name == "Alpha"));
                PropertyInfo pinfoBeta = Array.Find(pinfos, (o => o.Name == "Beta"));
                string nomAlpha = pinfoAlpha.Name;
                string nomBeta = pinfoBeta.Name;
                if ((string)text == nomAlpha)
                {
                    object valAlpha = pinfoAlpha.GetValue(this, null);
                    pinfoGamma.SetValue(this, valAlpha, null);
                }
                else if ((string)text == nomBeta)
                {
                    object valBeta = pinfoBeta.GetValue(this, null);
                    pinfoGamma.SetValue(this, valBeta, null);
                }
            }
            #endregion
     
     
            #region  NotifyPropertyChanged
     
            public event PropertyChangedEventHandler PropertyChanged;
            private void Raise(string nameProp)
            {
                PropertyChangedEventHandler h = PropertyChanged;
                if (h != null)
                    h(this, new PropertyChangedEventArgs(nameProp));
            }
            #endregion
        }
    }
    Son form User qui permet de saisir les 3 props CLR Gamma,Alpha et Beta et de l'observer en action:

    Code XAML : 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
    <Window x:Class="WpfWatcherDP.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfWatcherDP" 
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <StackPanel
                Margin="5"
                Grid.Column="0">
                <Label Content="Input Gamma "/>
                <TextBox 
                Text="{Binding Gamma, ElementName=ctl,UpdateSourceTrigger=PropertyChanged}"/>
                <Label Content="Input Alpha "/>
                <TextBox 
                Text="{Binding Alpha, ElementName=ctl,UpdateSourceTrigger=PropertyChanged}"/>
                <Label Content="Input Beta "/>
                <TextBox 
                Text="{Binding Beta, ElementName=ctl,UpdateSourceTrigger=PropertyChanged}"/>
     
                <Border
                    Margin="5"
                    BorderBrush="Blue" BorderThickness="2">
                    <local:UserControl1
                        x:Name="ctl"
                            />
                </Border>
            </StackPanel>
            <StackPanel
                Grid.Column="1"
                Margin="20">
                <Label 
                    Margin="5"
                    FontSize="12" FontStyle="Italic"
                    Content="Tb bindé à Gamma"/>
                <TextBlock 
                    Text="{Binding Gamma, ElementName=ctl,UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>
        </Grid>
    </Window>
    Exemple 1 sur un Custom Control:
    code xaml du fichier Generic.xaml:

    Code XAML : 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
    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfWatcherDP">
     
     
        <Style TargetType="{x:Type local:CustomControl}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:CustomControl}">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                            <Grid>
                                <DockPanel >
                                    <Label 
                    Content="Gamma "
                    MinWidth="50"/>
                                    <TextBlock 
                VerticalAlignment ="Center"
                Text="{Binding Gamma,RelativeSource={
                RelativeSource 
                Mode=FindAncestor,AncestorType={x:Type local:CustomControl}}}"/>
                                </DockPanel>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>

    code behind.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
    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
    namespace WpfWatcherDP
    {
        public class CustomControl : Control, INotifyPropertyChanged
        {
            private DPWatcher<string> watcher;
            static CustomControl()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
            }
            #region Alpha
            private string _alpha = "valeur pour alpha";
            public string Alpha
            {
                get { return _alpha; }
                set
                {
                    if (_alpha != value)
                    {
                        _alpha = value;
                        Raise("Alpha");
                    }
                }
            }
            #endregion
     
            #region  Beta
            private string _beta = "Valeur pour beta";
            public string Beta
            {
                get { return _beta; }
                set
                {
     
                    if (_beta != value)
                    {
                        _beta = value;
                        Raise("Beta");
                    }
     
                }
            }
            #endregion
     
            #region  Gamma
            private string _gamma ;
            public string Gamma
            {
                get { return _gamma; }
                set
                {
                    if (_gamma != value)
                    {
                        _gamma = value;
                        this.watcher =
                        new DPWatcher<string>(this, "Gamma");
                        this.watcher.PropertyChanged += new EventHandler(watcher_PropertyChanged);
                        Raise("Gamma");
                    }
     
                }
            }
     
            private void watcher_PropertyChanged(object sender, EventArgs e)
            {
                DPWatcher<string> currentWatcher = (DPWatcher<string>)sender;
                var text = currentWatcher.Value;
     
                CustomControl ctl = currentWatcher.Target as CustomControl;
                PropertyInfo[] pinfos = typeof(CustomControl).GetProperties();
                PropertyInfo pinfoGamma = Array.Find(pinfos, (o => o.Name == "Gamma"));
                PropertyInfo pinfoAlpha = Array.Find(pinfos, (o => o.Name == "Alpha"));
                PropertyInfo pinfoBeta = Array.Find(pinfos, (o => o.Name == "Beta"));
                string nomAlpha = pinfoAlpha.Name;
                string nomBeta = pinfoBeta.Name;
                if ((string)text == nomAlpha)
                {
                    object valAlpha = pinfoAlpha.GetValue(this, null);
                    pinfoGamma.SetValue(this, valAlpha, null);
                }
                else if ((string)text == nomBeta)
                {
                    object valBeta = pinfoBeta.GetValue(this, null);
                    pinfoGamma.SetValue(this, valBeta, null);
                }
     
            }
            #endregion
     
     
            #region  NotifyPropertyChanged
     
            public event PropertyChangedEventHandler PropertyChanged;
            private void Raise(string nameProp)
            {
                PropertyChangedEventHandler h = PropertyChanged;
                if (h != null)
                    h(this, new PropertyChangedEventArgs(nameProp));
            }
            #endregion 
        }
    }
    code xaml du form :

    Code XAML : 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
    <Window x:Class="WpfWatcherDP.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:local="clr-namespace:WpfWatcherDP" 
            Title="Window1" Height="300" Width="300">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <StackPanel
                Margin="5"
                Grid.Column="0">
                <Label Content="Input Gamma "/>
                <TextBox 
                Text="{Binding Gamma, ElementName=ctl,UpdateSourceTrigger=PropertyChanged}"/>
                <Label Content="Input Alpha "/>
                <TextBox 
                Text="{Binding Alpha, ElementName=ctl,UpdateSourceTrigger=PropertyChanged}"/>
                <Label Content="Input Beta "/>
                <TextBox 
                Text="{Binding Beta, ElementName=ctl,UpdateSourceTrigger=PropertyChanged}"/>
                <Border
                    Margin="5"
                    BorderBrush="Blue" BorderThickness="2">
                    <local:CustomControl
                        x:Name="ctl"
                            />
                </Border>
            </StackPanel>
            <StackPanel
                Grid.Column="1"
                Margin="20">
                <Label 
                    Margin="5"
                    FontSize="12" FontStyle="Italic"
                    Content="Tb bindé à Gamma"/>
                <TextBlock 
                    Text="{Binding Gamma, ElementName=ctl}"/>
            </StackPanel>
        </Grid>
    </Window>
    bon code ...

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, 18h24
  2. Binding sur une propriété
    Par Villard.patrick dans le forum Silverlight
    Réponses: 5
    Dernier message: 09/12/2009, 18h52
  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, 16h44
  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, 19h38
  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, 11h35

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