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 : passer un paramètre personnalisé à un contrôle utilisateur


Sujet :

Windows Presentation Foundation

  1. #1
    Membre actif
    Avatar de adaneels
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2006
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Août 2006
    Messages : 236
    Points : 210
    Points
    210
    Par défaut WPF : passer un paramètre personnalisé à un contrôle utilisateur
    Bonjour à vous,

    J'ai créé un contrôle utilisateur qui prend pour paramètre un objet d'un type personnalisé.
    A regarder les articles sur le sujet, je pense avoir compris les propriétés de dépendances et comment utiliser le contrôle utilisateur. Je n'arrive par contre pas à comprendre comment lui passer en paramètre un objet créé en code behind.

    Pour plus de clarté, j'ai reproduit le problème dans un projet simple :
    le code XAML du contrôle :
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <UserControl x:Class="WpfApplication1.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="150" d:DesignWidth="200">
        <Grid Height="144" Width="auto">
            <ComboBox Height="24" HorizontalAlignment="Stretch" Name="comboBox1" VerticalAlignment="top" Width="auto" SelectionChanged="comboBox1_SelectionChanged" />
            <ListBox Height="103" HorizontalAlignment="Stretch" Margin="0,30,0,0" Name="listBox1" VerticalAlignment="Stretch" Width="auto" />
        </Grid>
    </UserControl>

    Le code behind du contrôle utilisateur :
    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
      public partial class UserControl1 : UserControl
      {
     
        public static DependencyProperty ParcVoituresProperty = DependencyProperty.Register(
            "ParcVoitures", typeof(string), typeof(Parc));
     
        public Parc ParcVoitures
        {
          get
          {
            return (Parc)GetValue(ParcVoituresProperty);
          }
          set
          {
            SetValue(ParcVoituresProperty, value);
          }
        }
     
        public UserControl1()
        {
          InitializeComponent();
          if (ParcVoitures != null)
          {
            // remplissage de la combobox et de la listbox
            comboBox1.ItemsSource = ParcVoitures.lsVoitures.Select(x => x.Modele).Distinct();
            if (comboBox1.Items.Count > 1)
              comboBox1.SelectedIndex = 0;
            LoadVoitures();
          }
        }
     
        public void  LoadVoitures() {
          listBox1.ItemsSource = ParcVoitures.lsVoitures.Where(x => x.Marque == comboBox1.SelectedValue.ToString()).Select(x => x.Modele);
        }
     
        private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
          LoadVoitures();
        }
      }

    Le but du contrôle ci-dessus : un visualiseur d'un objet de type "Parc".

    Le type "Parc" :
    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
      public class Parc
      {
        public List<Voiture> lsVoitures;
     
        public Parc()
        {
          lsVoitures = new List<Voiture>();
          lsVoitures.Add(new Voiture("Peugeot", "308"));
          lsVoitures.Add(new Voiture("Renault", "Logan"));
          lsVoitures.Add(new Voiture("Peugeot", "407"));
          lsVoitures.Add(new Voiture("Audi", "R8"));
          lsVoitures.Add(new Voiture("Audi", "A3"));
          lsVoitures.Add(new Voiture("Renault", "R25"));
        }
      }
     
      public class Voiture
      {
        public string Marque;
        public string Modele;
     
        public Voiture(string pMarque, string pModele)
        {
          this.Marque = pMarque;
          this.Modele = pModele;
        }
      }
    }

    L'utilisation dans ma fenêtre principale (c'est là que je bloque) :
    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="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:myCtrl="clr-namespace:WpfApplication1"
        Title="Window1" Height="300" Width="300">
        <Window.Resources>
            <ObjectDataProvider x:Key="MesVoitures" 
                            ObjectType="{x:Type myCtrl:Parc}" ObjectInstance="MonParc" /> <!-- provoque une exception System.InvalidOperationException : "ObjectDataProvider ne peut se voir assigner qu'un ObjectType ou un ObjectInstance, pas les deux." -->
        </Window.Resources>
        <Grid>
            <myCtrl:UserControl1 ParcVoitures="{Binding Source={StaticResource MesVoitures}}"  HorizontalAlignment="Left" x:Name="userControl11" VerticalAlignment="Top" Height="195" Width="254" />
        </Grid>
    </Window>

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      public partial class MainWindow : Window
      {
        Parc MonParc = new Parc();
     
        public MainWindow()
        {
          InitializeComponent();
        }
      }

    Le but est d'utiliser "MonParc" qui va subir des traitements en tâche de fond et de passer son instance au contrôle utilisateur qui permet de visualiser son contenu (ici, dans l'exemple, pas de mécanisme de mise à jour, je veux simplement réussir à lui passer l'instance de l'objet!).

    Je comprends dans le message d'exception que je ne fais pas comme il faut.
    Cependant, j'ai beau faire des recherches, j'avoue que j'ai du mal avec le binding via XAML.

    Comment faire ?

    Note sur mes essais :
    J'ai essayé en passant par l'attribut "MethodName=GetVoitures" à la place de "ObjectInstance=MonParc" mais lors du passage dans le constructeur du contrôle utilisateur, la propriété "ParcVoitures" est nulle.


    En pièce jointe le projet (Visual Studio 2010) décrit ci-dessus.
    Fichiers attachés Fichiers attachés
    --
    Arnaud DANEELS

  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 : 49
    Localisation : Belgique

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

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Points : 3 568
    Points
    3 568
    Par défaut
    Ta dependencyproperty n'est pas bien déclarée. essaye plutot :

    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
    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
     
    namespace WpfApplication1
    {
      /// <summary>
      /// Logique d'interaction pour UserControl1.xaml
      /// </summary>
      public partial class UserControl1 : UserControl
      {
     
        public static DependencyProperty ParcVoituresProperty = DependencyProperty.Register(
            "ParcVoitures", typeof(Parc), typeof(UserControl1), new PropertyMetadata((o,e) =>
                                                                                         {
                                                                                             var pv = o as UserControl1;
                                                                                             if (pv != null)
                                                                                                 pv.ttt();
                                                                                         }));
     
        public Parc ParcVoitures
        {
          get
          {
              return (Parc)GetValue(ParcVoituresProperty);
          }
          set
          {
            SetValue(ParcVoituresProperty, value);
          }
        }
     
        public UserControl1()
        {
          InitializeComponent();
          if (ParcVoitures != null)
          {
              ttt();
          }
        }
     
          public void ttt()
          {
              comboBox1.ItemsSource = ParcVoitures.lsVoitures.Select(x => x.Modele).Distinct();
              if (comboBox1.Items.Count > 1)
                  comboBox1.SelectedIndex = 0;
              LoadVoitures();
          }
        public void  LoadVoitures() {
          listBox1.ItemsSource = ParcVoitures.lsVoitures.Where(x => x.Marque == comboBox1.SelectedValue.ToString()).Select(x => x.Modele);
        }
     
        private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
          LoadVoitures();
        }
      }
    }

    Mainwindow.XAML:

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        <Window.Resources>
            <ObjectDataProvider x:Key="MesVoitures" 
                           />
        </Window.Resources>

    MainWindow.cs
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
          var odp = this.FindResource("MesVoitures") as ObjectDataProvider;
          odp.ObjectInstance = MonParc;
    Microsoft MVP : Windows Platform

    MCPD - Windows Phone Developer
    MCPD - Windows Developer 4

    http://www.guruumeditation.net

    “If debugging is the process of removing bugs, then programming must be the process of putting them in.”
    (Edsger W. Dijkstra)

  3. #3
    Membre actif
    Avatar de adaneels
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2006
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Août 2006
    Messages : 236
    Points : 210
    Points
    210
    Par défaut
    Autant pour moi pour la déclaration de la DependencyProperty, une erreur lors de la reproduction du problème.

    En continuant mon cheminement, je suis arrivé au même point mais sans la création de la PropertyMetadata, ce qui faisait que mon paramètre était créé après l'initialisation du contrôle utilisateur.

    Là, ça marche impec, manque plus qu'à répercuter cette méthode dans mon projet.

    Merci !
    --
    Arnaud DANEELS

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 28/12/2014, 11h24
  2. [C#] Intégration contrôle utilisateur déplaçable WPF dans WinForm
    Par Jean-Charles01 dans le forum Développement Windows
    Réponses: 0
    Dernier message: 19/10/2011, 16h02
  3. [XL-2007] Passer en paramètre une plage de cellules selectionnée par l'utilisateur !
    Par mermar dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 05/10/2011, 20h55
  4. Réponses: 2
    Dernier message: 17/07/2008, 19h26
  5. Réponses: 2
    Dernier message: 20/05/2008, 10h03

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