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 :

Lier une combo à plusieurs ObjectDataProvider


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut Lier une combo à plusieurs ObjectDataProvider
    Salut,

    Je suis en train de créer une petite application sans prétention. J'ai une combo pour choisir un environnement et un tabcontrol avec deux grilles.
    Le code suivant fonctionne.
    En resource:
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <ObjectDataProvider x:Key="Jobs" ObjectType="{x:Type data:JobManager}" MethodName="GetJobHistoryByEnvironment">
                <ObjectDataProvider.MethodParameters>
                    <system:String>DEV</system:String>
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>
    La combo:
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <ComboBox Grid.Column="2" HorizontalAlignment="Stretch" Padding="0" Margin="3" x:Name="environmentComboBox">
                        <ComboBoxItem>DEV</ComboBoxItem>
                        <ComboBoxItem>TEST</ComboBoxItem>
                        <ComboBoxItem>PROD</ComboBoxItem>
                        <ComboBox.Text>
                            <Binding Source="{StaticResource Jobs}" Path="MethodParameters[0]" BindsDirectlyToSource="True" UpdateSourceTrigger="PropertyChanged" />
                        </ComboBox.Text>
                    </ComboBox>
    La première grille:
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    <DataGrid Name="jobGrid" ItemsSource="{Binding Source={StaticResource Jobs}}" />

    Maintenant je souhaiterais ajouter un deuxième ObjectDataProvider pour remplir ma deuxième grille. Je ne peux évidemment pas créer une deuxième ligne <Binding> dans la combo. Comment binder le paramètre du deuxième ObjectDataProvider sur la combo ?

    Merci
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    A mon avis ObjectDataProvider n'est pas la bonne solution... C'est peu pratique à utiliser, et pas assez souple pour les scénarios complexes.

    Est-ce que tu appliques le pattern MVVM ? Si oui le plus simple est de faire un truc comme ça dans ton ViewModel :

    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
    private string _environment;
    public string Environment
    {
        get { return _environment; }
        set
        {
            _environment = value;
            OnPropertyChanged("Environment");
            OnPropertyChanged("JobHistory");
            OnPropertyChanged("FooBars");
        }
    }
     
    public IEnumerable<JobHistoryEntry> JobHistory
    {
        get { return JobManager.GetJobHistoryByEnvironment(_environment); }
    }
     
    public IEnumerable<FooBar> FooBars
    {
        get { return JobManager.GetFooBarsByEnvironment(_environment); }
    }

    Tu bindes la ComboBox sur Environment, et les DataGrids sur JobHistory et FooBars (ou quel que soit son nom). Quand tu changes l'élément sélectionné du ComboBox, ça met à jour Environment, ce qui déclenche la réévaluation de JobHistory et FooBars (à cause du OnPropertyChanged).

  3. #3
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    J'espérais que tu répondrais
    Pour l'instant, pas de MVVM mais avec l'exemple que tu donnes ça me semble bien plus efficace comme approche.
    Sinon pour répondre strictement à ma question initiale, il semblerait que je doive créer un MultiBinding.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Développer en WPF sans MVVM, c'est un peu du masochisme... Quand je me suis mis à WPF, je trouvais ça horriblement compliqué et peu pratique par rapport à Windows Forms, j'avais l'impression d'un retour en arrière. Et puis j'ai découvert MVVM, et c'est à partir de là que je me suis mis à aimer WPF

    Citation Envoyé par SaumonAgile Voir le message
    Sinon pour répondre strictement à ma question initiale, il semblerait que je doive créer un MultiBinding.
    Bah je vois pas trop comment ça s'appliquerait dans ce contexte en fait...

  5. #5
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut CHANGER DE DATACONTEXT AVEC OBJECTDATAPROVIDER
    Bonjour SaumonAgile & TomLev
    Quoique le MVMM soit le pattern le plus approprie pour le WPF comme dit par Tomlev,neanmoins pour une petite appli comme celle de SaumonAgile on peut faire entorse....
    Pour le ObjectDataProvider voici ce qu'en dit MSDN Doc fr:
    Cette classe est également utile lorsque vous souhaitez remplacer votre objet de source de liaison actif par un autre objet et avoir toutes les liaisons associées mises à jour.
    Compte-tenu de cette remarque tu peux donc "switcher" le combo entre tes 2 datacontext des 2 datagrids...sans aucun multibinding (qu'il ne faut pas confondre avec multiple datacontext) car nous avons dans ton besoin de changer non de props mais de contexte(source).Comme le montre ce bout de code:
    code behind des classes:
    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
    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
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
     
    //classe  JobsHistory
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace WpfSwitchObjectDataProvider
    {
        public class JobsHistory
        {
            public string EnvJob { get; set; }
            public string NameJob { get; set; }
            public DateTime DateJob { get; set; }
        }
    }
    //classe JobManager
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections.ObjectModel;
    namespace WpfSwitchObjectDataProvider
    {
        public class JobManager
        {
     
    	    private static  ObservableCollection<JobsHistory> listJobs;
            public static ObservableCollection<JobsHistory> GetJobHistoryByEnvironment(String sEnv) 
            {
                JobManager.listJobs = new ObservableCollection<JobsHistory>();
                JobsHistory instanceJobs;
                switch (sEnv)
                {
                    case "DEV":
                        for (int i = 0; i < 5; i++)
    			        {
                            instanceJobs = new JobsHistory();
                            instanceJobs.NameJob = "Job-DEV-Name" + (i + 1).ToString();
                            instanceJobs.DateJob = DateTime.Now;
                            instanceJobs.EnvJob = sEnv;
                            JobManager.listJobs.Add(instanceJobs);
    			        }
                        break;
                    case "TEST":
                        for (int i = 0; i < 3; i++)
                        {
                            instanceJobs = new JobsHistory();
                            instanceJobs.NameJob = "Job-TEST-Name" + (i + 1).ToString();
                            instanceJobs.DateJob = DateTime.Now;
                            instanceJobs.EnvJob = sEnv;
                            JobManager.listJobs.Add(instanceJobs);
                        }
                        break;
                    case "PROD":
                        for (int i = 0; i < 6; i++)
                        {
                            instanceJobs = new JobsHistory();
                            instanceJobs.NameJob = "Job-PROD-Name" + (i + 1).ToString();
                            instanceJobs.DateJob = DateTime.Now;
                            instanceJobs.EnvJob = sEnv;
                            JobManager.listJobs.Add(instanceJobs);
                        }
                        break;
     
                    default:
                        break;
                }
                return JobManager.listJobs;
            }
        }
    }
    //  FooBars
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace WpfSwitchObjectDataProvider
    {
        public class FooBars
        {
            public string EnvFooBars { get; set; }
            public string NameFooBars { get; set; }
            public DateTime DateFooBars { get; set; }
        }
    }
    //classe   FooBarManager
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections.ObjectModel;
    namespace WpfSwitchObjectDataProvider
    {
        public class FooBarManager
        {
     
            private static ObservableCollection<FooBars> listFooBars;
            public static ObservableCollection<FooBars> GetFooBarsByEnvironment(String sEnv)
            {
                FooBarManager.listFooBars = new ObservableCollection<FooBars>();
                FooBars instanceFooBars;
                switch (sEnv)
                {
                    case "DEV":
                        for (int i = 0; i < 5; i++)
                        {
                            instanceFooBars = new FooBars();
                            instanceFooBars.NameFooBars = "FooBars-DEV-Name" + (i + 1).ToString();
                            instanceFooBars.DateFooBars = DateTime.Now;
                            instanceFooBars.EnvFooBars = sEnv;
                            FooBarManager.listFooBars.Add(instanceFooBars);
                        }
                        break;
                    case "TEST":
                        for (int i = 0; i < 3; i++)
                        {
                            instanceFooBars = new FooBars();
                            instanceFooBars.NameFooBars = "FooBars-TEST-Name" + (i + 1).ToString();
                            instanceFooBars.DateFooBars = DateTime.Now;
                            instanceFooBars.EnvFooBars = sEnv;
                           listFooBars.Add(instanceFooBars);
                        }
                        break;
                    case "PROD":
                        for (int i = 0; i < 6; i++)
                        {
                            instanceFooBars = new FooBars();
                            instanceFooBars.NameFooBars = "FooBars-PROD-Name" + (i + 1).ToString();
                            instanceFooBars.DateFooBars = DateTime.Now;
                            instanceFooBars.EnvFooBars = sEnv;
                            FooBarManager.listFooBars.Add(instanceFooBars);
                        }
                        break;
     
                    default:
                        break;
                }
                return FooBarManager.listFooBars;
            }
        }
    }
    //le winform
    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 WpfSwitchObjectDataProvider
    {
        /// <summary>
        /// Logique d'interaction pour Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            private ObjectDataProvider changeProviderJobs ; 
    	    private ObjectDataProvider changeProviderFoobars ;
            public Window1()
            {
                InitializeComponent();
                //initialise les providers
                changeProviderJobs = (ObjectDataProvider)this.FindResource("myJobs");
                changeProviderFoobars = (ObjectDataProvider)this.FindResource("myFooBars");
            }
     
            private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
     
                TabControl tabSender;
                TabItem ti;
     
    		tabSender = sender as  TabControl;
            if(tabSender ==null ) return;
    		ti = tabSender.SelectedItem as TabItem;
            //Switch DataContext  
             if(ti.Name==this.JobsTab.Name)
    	        {
                    this.environmentComboBox.DataContext = changeProviderJobs;
    	        }
             else if(ti.Name==this.FooBarsTab.Name)
    	        {
    			   this.environmentComboBox.DataContext = changeProviderFoobars;
    	        }
            }
        }
    }

    code xaml winform
    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
    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
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
     
    <Window x:Class="WpfSwitchObjectDataProvider.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:my="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
        xmlns:local="clr-namespace:WpfSwitchObjectDataProvider"
        Title="Switching Between DataContext with ObjectDataProvider"
        Height="300" Width="300">
        <Window.Resources>
            <!--1er provider-->
            <ObjectDataProvider 
                x:Key="myJobs" 
                ObjectType="{x:Type local:JobManager}" 
                MethodName="GetJobHistoryByEnvironment">
                <ObjectDataProvider.MethodParameters>
                    <sys:String>DEV</sys:String>
                </ObjectDataProvider.MethodParameters >
            </ObjectDataProvider>
            <!--2eme provider-->
            <ObjectDataProvider 
                x:Key="myFooBars" 
                ObjectType="{x:Type local:FooBarManager}" 
                MethodName="GetFooBarsByEnvironment">
                <ObjectDataProvider.MethodParameters>
                    <sys:String>DEV</sys:String>
                </ObjectDataProvider.MethodParameters >
            </ObjectDataProvider>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="100*" ></RowDefinition>
                <RowDefinition Height="60" ></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100*"></ColumnDefinition>
                <ColumnDefinition Width="100*"></ColumnDefinition>
                <ColumnDefinition Width="100"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <!--noter que Combo la prop Source est initilise à null Provider-->
            <!--prop determine au run-time-->
            <ComboBox 
                    Grid.Row="1"
                    Grid.Column="2" 
                    HorizontalAlignment="Stretch" 
                    Padding="0" 
                    Margin="3" 
                    x:Name="environmentComboBox"
                    Text="{Binding   Path=MethodParameters[0], BindsDirectlyToSource=True, UpdateSourceTrigger=PropertyChanged}">>
                <ComboBoxItem>DEV</ComboBoxItem>
                <ComboBoxItem>TEST</ComboBoxItem>
                <ComboBoxItem>PROD</ComboBoxItem>
            </ComboBox>
            <!--tablcontrol avec nos 2 grids pour chacun des providers-->
            <Border 
                Background="Gainsboro"
                BorderBrush="Blue" 
                BorderThickness="1"
                CornerRadius="15"
                Grid.Column="0"
                Grid.ColumnSpan="3"
                Padding="10">
                <TabControl 
                Background="Transparent"
                SelectionChanged="TabControl_SelectionChanged">
                    <TabItem  
                          Name="JobsTab"
                          Background="Lime"
                          BorderThickness="2,2,2,0">
                        <TabItem.Header>
                            <StackPanel 
                            Orientation="Horizontal">
                                <Ellipse 
                                Width="20" 
                                Height="10" 
                                Fill="Red"/>
                                <TextBlock 
                                FontSize="14" 
                                FontFamily="arial" 
                                FontWeight="Bold" 
                                TextAlignment="Center">Jobs</TextBlock>
                            </StackPanel>
                        </TabItem.Header>
                        <my:DataGrid 
                            Name="JobsGrid"
                            AutoGenerateColumns="true" 
                            VerticalAlignment="Top"
                            ItemsSource="{Binding Source={StaticResource myJobs}}" 
                            Background="DarkBlue" 
                            Foreground="DarkGoldenrod">
                        </my:DataGrid>
                    </TabItem>
                    <TabItem
                    Name="FooBarsTab"
                    Background="LightYellow" 
                    BorderThickness="2,2,2,0">
     
                        <TabItem.Header>
                            <StackPanel 
                            Orientation="Horizontal">
                                <Ellipse 
                                Width="20" 
                                Height="10" 
                                Fill="YellowGreen"/>
                                <TextBlock FontSize="14" 
                                       FontFamily="arial" 
                                       FontWeight="Bold" 
                                       TextAlignment="Center">FooBars</TextBlock>
                            </StackPanel>
                        </TabItem.Header>
                        <!--Bind TextBlock.Text to the TextBox on the first TabItem.-->
                        <my:DataGrid 
                                Name="PersonGrid"
                                AutoGenerateColumns="true" 
                                VerticalAlignment="Top"  
                                ItemsSource="{Binding Source={StaticResource myFooBars}}"
                                Background="DarkBlue" 
                                Foreground="DarkRed">
                        </my:DataGrid>
                    </TabItem>
                </TabControl>
            </Border>
     
        </Grid>
    </Window>
    bon code.................

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

Discussions similaires

  1. [2.x] Lier une entité avec plusieurs entités
    Par LEF97 dans le forum Symfony
    Réponses: 2
    Dernier message: 21/11/2013, 07h55
  2. [PDO] Lier une valeur à plusieurs paramètres identiques
    Par Bisûnûrs dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 19/06/2013, 09h00
  3. [AC-2007] Imprimer plusieurs fois un Etat selon chaque ligne d'une combo
    Par symbabeauchat dans le forum IHM
    Réponses: 2
    Dernier message: 03/12/2011, 20h09
  4. Réponses: 1
    Dernier message: 21/04/2008, 12h06
  5. lier un combo avec une zone de texte
    Par joss56 dans le forum IHM
    Réponses: 2
    Dernier message: 28/11/2006, 16h11

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