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 :

Modification de données depuis une fenêtre secondaire.


Sujet :

Windows Presentation Foundation

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut Modification de données depuis une fenêtre secondaire.
    Bonjour à tous (encore moi ^^),


    Je voulais savoir si il était possible en WPF d'éditer des données présentent dans ma fenêtre principale en ouvrant une autre fenêtre (depuis cette fenêtre principale) et qui servirait a modifier les données d'une class ? J'ai chercher un peu sur internet mais a part des string il semblerait difficile de faire transiter d'autres types de données :/


    Cordialement,

    Paibok

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    S'il s'agit de la même application, ou est le problème?
    Il n'y a pas de réponse toute faite parceque ca va dependre entièrement de ton organisation du code et de ta gestion de fenêtre.
    Mais si tu es dans une même application alors tu as plein de moyen de partager tes données comme l'utilisation d'un locator, d'une classe static, d' une messagerie,ou encore une référence directe depuis la page appelante vers la nouvelle fenêtre (déconseillé)...

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Bonjour,

    Oui il s'agit de la meme application, j'ai une fenêtre MainWindow et une autre que j'ai appelée Editor.

    Toutes les données que je souhaite modifier se trouve dans une class que voici :

    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
    public class TypesActivity
            {
                public string Name { get; set; }
                public SelectionMode Selection { get; set; }
                public ObservableCollection<string> Elements { get; set; }
                public ObservableCollection<Label> AssociatedLabels { get; set; }
     
     
                public TypesActivity()
                {
                    Elements = new ObservableCollection<string>();
                    AssociatedLabels = new ObservableCollection<Label>();
                }
     
                public override string ToString()
                {
                    return Name;
                }
            }
    Vous remarquerez qu'à l'intérieure de cette class est imbriquée une autre class que voici :

    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
    public class Label
            {
                public string Name { get; set; }
                public ObservableCollection<Object> Elements { get; set; }
                public TimeSpan startingTime { get; set; }
                public TimeSpan endingTime { get; set; }
                public int startingFrame { get; set; }
                public int endingFrame { get; set; }
                public int bits { get; set; }
     
                public Label()
                {
                    Elements = new ObservableCollection<Object>();
                }
     
                public override string ToString()
                {
                    return Name;
                }
     
            }
    Toutes les données dont j'ai besoin se trouve dans une liste tel que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public ObservableCollection<TypesActivity> Types = new ObservableCollection<TypesActivity>();
    J'ai donc un bouton dans ma MainWindow avec un gestionnaire d'evennement associé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    private void editorClick(object sender, RoutedEventArgs e)
            {
                var editor = new Vlc.DotNet.Wpf.Samples.EditorOfLabels();
                editor.ShowDialog();
            }

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    Une modification simple de ton code est de modifier le constructeur de EditorOfLabels pour qu'il prenne un objet du type que tu as besoin, ou tu rajoutes une propriété que tu affectes apres ton instanciation. Ensuite dans ton code il suffira sans doute d'associer le datacontext à cet objet.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Merci pour ces quelques indication Micka, je travail dessus en ce moment meme et j'ai réussi quelques trucs. Je repasserai surement dans les prochain jour si j'ai besoin d'infos

  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
    a partir du moment ou c'est le meme objet qui se trouve dans un datatemplate et que ton binding est fait
    si tu change une valeur de cet objet (meme dans une autre fenetre) ca change partout
    si dans la fenete A tu as
    MonObjet mo = new MonObjet()
    this.datacontext = mo;

    et que tu ouvre la fenetre B
    B b = new B(mo);

    et que dans B tu as

    B(object o){
    this.datacontext = o;
    }

    si dans MonObjet tu as public string Nom ... (avec inotifypropertychanged actif)
    si tu le change dans B ca changera dans A ....
    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
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Salut Ikeas,

    Content de te revoir. Oui effectivement j'ai dors et déjà utilisé cette technique, ma variable étant de type référence j'ai réussi a créer mon éditeur très simplement il y a maintenant plusieurs jours cependant ce type référence me pose maintenant un problème car j'aimerais pouvoir intégrer un bouton "annuler" qui me permettrait d'annuler toutes les modifications effectués sur les labels. En soit rien de bien compliqué, juste a créer une deep copy de ma list au lancement de la fenêtre et a l'assigner en cas d'appuis sur le bouton annulé sauf qu'il semble très simple de créer une shadow copy mais pour une deep copy la façon la plus simple que j'ai pu observer jusqu'a maintenant reste a utiliser une sérialization. Pense tu que je dois m'enroienter dans cette voie ou a tu une meilleur suggestion ?

  8. #8
    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
    non c'est une bonne idée

    tu fait une copie (deep) soit par serialisation, soit en rajoutant la methode copyTo (ou les deux) etc...

    source.copyto(backup)
    tu travail sur l'element actif : source
    si tu clique annuler tu fais backup.copyto(source)

    voici des exemples sympa pour faire cela (ca utilise la serialisaion pour faire la copie)
    http://stackoverflow.com/questions/1...c-specifically
    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/

  9. #9
    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

    Depuis Net Framework ItemCollection de tout control dérivé de ItemsControl implemente IEditableCollectionView....Que sgnifie cela ?
    Qu'elle gère tout Class implémentant :
    - INotifyPropertyChanged
    - IEditableObject ,le must du must : son implémentation permet de valider ou annuler les modifs sur un instance du Class en cours d'edition ,ce qui éliminé l'inconvénient de l'avantage du Binding !!!
    l'exemple ci-après illustre la mécanique :
    1/ code behind .cs du class Data PurchaseItem :
    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
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
     
    // PurchaseItem implements INotifyPropertyChanged so that the 
        // application is notified when a property changes.  It 
        // implements IEditableObject so that pending changes can be discarded.
        public class PurchaseItem : INotifyPropertyChanged, IEditableObject
        {
            struct ItemData
            {
                internal string Description;
                internal double Price;
                internal DateTime OfferExpires;
            }
            ItemData copyData;
            ItemData currentData;
     
            public PurchaseItem()
                : this("New item", 0, DateTime.Now)
            {
            }
     
            public PurchaseItem(string desc, double price, DateTime endDate)
            {
                Description = desc;
                Price = price;
                OfferExpires = endDate;
            }
     
            public override string ToString()
            {
                return String.Format("{0}, {1:c}, {2:D}", Description, Price, OfferExpires);
            }
     
            public string Description
            {
                get { return currentData.Description; }
                set
                {
                    if (currentData.Description != value)
                    {
                        currentData.Description = value;
                        NotifyPropertyChanged("Description");
                    }
                }
            }
     
            public double Price
            {
                get { return currentData.Price; }
                set
                {
                    if (currentData.Price != value)
                    {
                        currentData.Price = value;
                        NotifyPropertyChanged("Price");
                    }
                }
            }
     
            public DateTime OfferExpires
            {
                get { return currentData.OfferExpires; }
                set
                {
                    if (value != currentData.OfferExpires)
                    {
                        currentData.OfferExpires = value;
                        NotifyPropertyChanged("OfferExpires");
                    }
                }
            }
     
            #region INotifyPropertyChanged Members
     
            public event PropertyChangedEventHandler PropertyChanged;
     
            private void NotifyPropertyChanged(String info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }
     
            #endregion
     
            #region IEditableObject Members
     
            public void BeginEdit()
            {
                copyData = currentData;
            }
     
            public void CancelEdit()
            {
                currentData = copyData;
                NotifyPropertyChanged("");
     
            }
     
            public void EndEdit()
            {
                copyData = new ItemData();
     
            }
     
            #endregion
     
        }
        public class ItemsForSale : ObservableCollection<PurchaseItem>
        {
            public ItemsForSale()
            {
                Add((new PurchaseItem("Snowboard and bindings", 120, new DateTime(2009, 1, 1))));
                Add((new PurchaseItem("Inside C#, second edition", 10, new DateTime(2009, 2, 2))));
                Add((new PurchaseItem("Laptop - only 1 year old", 499.99, new DateTime(2009, 2, 28))));
                Add((new PurchaseItem("Set of 6 chairs", 120, new DateTime(2009, 2, 28))));
                Add((new PurchaseItem("My DVD Collection", 15, new DateTime(2009, 1, 1))));
                Add((new PurchaseItem("TV Drama Series", 39.985, new DateTime(2009, 1, 1))));
                Add((new PurchaseItem("Squash racket", 60, new DateTime(2009, 2, 28))));
            }
     
        }
    2/ code xaml du ChangeItemWindow (form editor modal) :
    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
     
    <Window x:Class="EditingCollectionsSample.ChangeItemWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Add or Edit an Item" Height="200" Width="300"
        ResizeMode="NoResize">
        <Window.Resources>
            <Style TargetType="HeaderedContentControl">
                <Setter Property="Margin" Value="2"/>
                <Setter Property="Focusable" Value="False"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="HeaderedContentControl">
                            <DockPanel LastChildFill="False">
                                <ContentPresenter ContentSource="Header" DockPanel.Dock="Left" 
                                      Focusable="False" VerticalAlignment="Center"/>
                                <ContentPresenter ContentSource="Content" Margin="5,0,0,0" 
                                      DockPanel.Dock="Right" VerticalAlignment="Center"/>
                            </DockPanel>
     
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
     
            <Style TargetType="Button">
                <Setter Property="Width" Value="100"/>
                <Setter Property="Margin" Value="10,15,15,15"/>
     
            </Style>
        </Window.Resources>
        <StackPanel Margin="10" Width="250">
        <StackPanel.Resources>
     
        </StackPanel.Resources>
     
        <HeaderedContentControl Header="Description">
          <TextBox Width="150" Text="{Binding Path=Description, Mode=TwoWay}"/>
        </HeaderedContentControl>
        <HeaderedContentControl Header="Price">
          <TextBox Width="150" Text="{Binding Path=Price, Mode=TwoWay}"/>
        </HeaderedContentControl>
        <HeaderedContentControl Header="Date Offer Ends">
          <TextBox Width="150" Text="{Binding Path=OfferExpires, StringFormat=d, Mode=TwoWay}"/>
        </HeaderedContentControl>
        <StackPanel Orientation="Horizontal">
          <Button IsDefault="True" Click="Submit_Click">_Submit</Button>
          <Button IsCancel="True">_Cancel</Button>
        </StackPanel>
      </StackPanel>
    </Window>
    et son code simplistic 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
     
    public partial class ChangeItemWindow  : Window
        {
            public ChangeItemWindow()
            {
                InitializeComponent();
            }
     
            private void Submit_Click(object sender, RoutedEventArgs e)
            {
                DialogResult = true;
                Close();
            }
        }
    3/ code xaml du Form Main :
    <Window x:Class="EditingCollectionsSample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:EditingCollectionsSample"
    Title="Items for Sale">
    <StackPanel>
    <StackPanel.Resources>
    <src:ItemsForSale x:Key="MyData"/>

    <Style TargetType="Button">
    <Setter Property="Margin" Value="5"/>
    </Style>

    </StackPanel.Resources>

    <TextBlock FontSize="14" Margin="5" TextWrapping="Wrap">
    This sample lets users add and change items for sale in a ListView.
    The application uses the APIs that are provided by
    IEditableCollectionView and implemented by the ListView's
    ItemCollection to add and change items in the ListView's
    underlying source collection. Because the application
    leverages the APIs of IEditableCollectionView, it
    does not need to manipulate the source collection directly.
    </TextBlock>
    <ListView Name="itemsControl" ItemsSource="{StaticResource MyData}">
    <ListView.View>
    <GridView>
    <GridViewColumn Header="Item"
    DisplayMemberBinding="{Binding Path=Description}"/>
    <GridViewColumn Header="Price"
    DisplayMemberBinding="{Binding Path=Price, StringFormat=c}"/>
    </GridView>
    </ListView.View>
    </ListView>
    <StackPanel Orientation="Horizontal">
    <Button Name="add" Click="add_Click">Add</Button>
    <Button Name="edit" Click="edit_Click">Edit</Button>
    <Button Name="remove" Click="remove_Click">Remove</Button>
    </StackPanel>
    </StackPanel>
    </Window>

    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
     
     /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
     
     
            private void edit_Click(object sender, RoutedEventArgs e)
            {
                if (itemsControl.SelectedItem == null)
                {
                    MessageBox.Show("No item is selected");
                    return;
                }
     
                IEditableCollectionView editableCollectionView =
                            itemsControl.Items as IEditableCollectionView;
     
                // Create a window that prompts the user to edit an item.
                ChangeItemWindow win = new ChangeItemWindow();
                editableCollectionView.EditItem(itemsControl.SelectedItem);
                win.DataContext = itemsControl.SelectedItem;
     
                // If the user submits the new item, commit the changes.
                // If the user cancels the edits, discard the changes. 
                if ((bool)win.ShowDialog())
                {
                    editableCollectionView.CommitEdit();
                }
                else
                {
                    editableCollectionView.CancelEdit();
                }
            }
     
            private void add_Click(object sender, RoutedEventArgs e)
            {
                IEditableCollectionView editableCollectionView = itemsControl.Items as IEditableCollectionView; 
     
                if (!editableCollectionView.CanAddNew)
                {
                    MessageBox.Show("You cannot add items to the list.");
                    return;
                }
     
                // Create a window that prompts the user to enter a new
                // item to sell.
                ChangeItemWindow win = new ChangeItemWindow();
     
                //Create a new item to be added to the collection.
                win.DataContext = editableCollectionView.AddNew();
     
                // If the user submits the new item, commit the new
                // object to the collection.  If the user cancels 
                // adding the new item, discard the new item.
                if ((bool)win.ShowDialog())
                {
                    editableCollectionView.CommitNew();
                }
                else
                {
                    editableCollectionView.CancelNew();
                }
     
            }
     
            private void remove_Click(object sender, RoutedEventArgs e)
            {
                PurchaseItem item = itemsControl.SelectedItem as PurchaseItem;
     
                if (item == null)
                {
                    MessageBox.Show("No Item is selected");
                    return;
                }
     
                IEditableCollectionView editableCollectionView = 
                        itemsControl.Items as IEditableCollectionView; 
     
                if (!editableCollectionView.CanRemove)
                {
                    MessageBox.Show("You cannot remove items from the list.");
                    return;
                }
     
                if (MessageBox.Show("Are you sure you want to remove " + item.Description,
                                    "Remove Item", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                {
                    editableCollectionView.Remove(itemsControl.SelectedItem);
                }
            }
        }
    bon code ....

  10. #10
    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
    Re

    OUPS !!! lire : Depuis Net Framework 3.5 SP1 .....

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Salut MABROUKI,


    Merci pour ta réponse, tout fonctionne très bien


    Cordialement,

    Paibok

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Salut a tous,


    Je me permet de reposter ici car mon problème suit ce qui a été fait par conséquent je n'aurai pas a réexpliquer tout les détails. Si ma démarche n'est pas correcte, merci de me l'indiquer auquel cas je referai un autre post.


    Du coup mon problème se trouve maintenant sur l'actualisation de l'affichage des données. En effet lorsque je modifie un Label, les modifications sont bien prises en compte dans les données mais l'affichage au sein de ma ListBox de Label ne s'actualise pas. J'ai cru comprendre en regardant un peu sur internet qu'il fallait implémenter le INotifyPropertyChanged. Ce que j'ai fais via plusieurs méthodes mais je n'arrive pas a le faire fonctionner .. J'ai plusieurs hypothèses en tete mais par manque de tutos sur internet j'ai du mal a m'y retrouver .. En effet les personnes présente la plupart du temps juste leur façon de faire sans rien expliquer.


    Voici ce que moi j'ai fais :

    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
    public class TypesActivity : INotifyPropertyChanged
            {
                public string Name { get; set; }
                public SelectionMode Selection { get; set; }
                public ObservableCollection<string> Elements { get; set; }
                public ObservableCollection<Label> associatedLabels;
     
                public TypesActivity()
                {
                    Elements = new ObservableCollection<string>();
                    AssociatedLabels = new ObservableCollection<Label>();
                }
     
                public override string ToString()
                {
                    return Name;
                }
     
                public ObservableCollection<Label> AssociatedLabels
                {
                    get { return this.associatedLabels; }
                    set
                    {
                        if (this.associatedLabels != value)
                        {
                            this.associatedLabels = value;
                            NotifyPropertyChanged();
                        }
                    }
                }
     
     
                #region INotifyPropertyChanged Members
     
                public event PropertyChangedEventHandler PropertyChanged;
     
                private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = "")
                {
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                    }
                }
     
                #endregion
            }
    et


    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
    public class Label : INotifyPropertyChanged
            {
                private string name;
                public ObservableCollection<Object> Elements { get; set; }
                public string startingTime { get; set; }
                public string endingTime { get; set; }
                public int startingFrame { get; set; }
                public int endingFrame { get; set; }
                public int bits { get; set; }
     
                public Label()
                {
                    Elements = new ObservableCollection<Object>();
                }
     
     
     
                public override string ToString()
                {
                    return name;
                }
     
     
     
                public string Name
                {
                    get { return this.name; }
                    set
                    {
                        if (this.name != value)
                        {
                            this.name = value;
                            NotifyPropertyChanged();
                        }
                    }
                }
     
                #region INotifyPropertyChanged Members
     
                public event PropertyChangedEventHandler PropertyChanged;
     
                private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = "")
                {
                    if(PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                    }
                }
     
                #endregion
     
            }
    Sachant que j'ai bindé de la façon suivante :

    pour la Combobox :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ItemsSource="{Binding}"
    et pour la ListBox :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ItemsSource="{Binding SelectedItem.AssociatedLabels, ElementName=itemComboBox}"
    Avec le datacontext fixé sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public ObservableCollection<TypesActivity> Types = new ObservableCollection<TypesActivity>();

    Ca compile très bien mais rien ne se passe ..

    Merci d'avance.

  13. #13
    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
    pour information l'implementation de INotifyPropertyChanged se fait dans la classe avec la declaration de l'event
    et pour chacune des propriétés (faire) par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #region Name Property
    private string _Name;
    public string Name { 
    get { return _Name; }
    set { 
          _Name = value;
          // c# 6
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
         // sinon
         NotifyPropertyChanged("Name");
         }
    }
    #endregion
    et la ca devrait marcher
    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/

  14. #14
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Salut Ikeas ça fait un moment

    Merci pour ta réponse mais malheureusement non ça ne fonctionne pas ... La deuxième ligne ne passe pas sur mon visual studio (PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"))

    De plus est-il nécéssaire de l'appliquer a toutes les propriétés sachant que je ne bind que sur le nom ainsi j'ai seulement à envoyer une notification lorsque le nom change pour que l'affichage soit correct.

    N'est-il pas nécéssaire d'insérer quelque chose dans le xaml ? J'ai vu que certain rajoute Mode=TwoWay souvent.

    De plus le fait qu'il s'agisse d'une liste de TypeActivity contenant dans tous les cas une liste de Label ne pose t-il pas problème ? Est-il nécéssaire d'implémenter INotifyPropertyChanged a différents niveaux ?

    J'avoue que je maitrise pas du tout cette partie et le programme commencent à devenir un peu complexe, je me dis que le problème peut venir de plein d'endroits ce qui m'empêche encore plus d'y voir clair ...

    Merci d'avance.

  15. #15
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    Pour le message de Ikeas j'avoue ne pas comprendre ou il veut en venir. On utilise Invoke pour des problèmes de threads, mais là je n'en vois pas l'utilité.

    Je ne sais pas trop ce que tu modifies dans tes labels, mais là tu ne notifies seulement le changement de la propriété Name.
    Pour le TwoWay c'est lorsque tu veux que ton IHM modifie la donnée de ton modèle (donc dans ton cas les controls de l'éditeur de label devrait etre en twoway).
    Ensuite as tu redéfinis le template de ta listbox ?
    Je vois que tu as fais un override du toString je me demande si tu ne l'as pas laissé tel que, et donc par défaut c'est le ToString() de chaque item que la listebox affiche. Dans ce cas là la listebox ne s'est pas abonné à PropertyChanged du name puisque elle n'en a pas l'utilité.

  16. #16
    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
    l'interface INotifyPropertyChanged est
    1/exigible en WPF pour les class Data en WPF
    2/doit être implémenter pour tous les props du class ...
    3/le paramètre du Handler RaisePropertyChanged est le nom de prop(un string)
    Donc le "boiler-plate code" (code répétitif) est inévitable lorsqu'on a un class avec beaucoup de props ..
    4/le Mode=TwoWay est nécessaire si on veut que le class Data soit mis à jour en fonction du Control UI...

    5/il faut éliminer le tostring ()

    6/Le fait qu'un prop soit un List<> ne change rien, il suffit de se binder au prop List<>...

    7/NB : quand on fait un renommage de prop il ne faut pas oublier de mettre à jour le nom de prop ou string passé en paramètre du Handler RaisePropertyChanged


    class TypeActivity:
    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
     
     
    public class TypeActivity : INotifyPropertyChanged
        {
     
     
            public TypeActivity()
                : this("New Activity", new ObservableCollection<Label>())
            {
                AssociatedLabels = new ObservableCollection<Label>();
            }
            public TypeActivity(string pname, ObservableCollection<Label> liste)
            {
               Name = pname;
               AssociatedLabels  = liste;
            }
            private  string name;
            public string Name
            {
                get { return this.name ; }
                set
                {
                    if (this.name != value)
                    {
                        this.name = value;
                        RaisePropertyChanged("Name");
                    }
                }
            }
            private  ObservableCollection<Label> associatedLabels;
            public ObservableCollection<Label> AssociatedLabels
            {
                get { return this.associatedLabels; }
                set
                {
                    if (this.associatedLabels != value)
                    {
                        this.associatedLabels = value;
                        RaisePropertyChanged("AssociatedLabels");
                    }
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged(String info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }
     
     
        }
    un code semblable pour le class Label:
    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
     
     
     
     
        public class Label : INotifyPropertyChanged
        {
     
            public Label(): this("New Label", new ObservableCollection<string>())
            {
            }
            public Label(string n, ObservableCollection<string> liste)
            {
               Name = n;
               Elements = liste;
            }
     
     
     
     
            private string name;
            public string Name
            {
                get { return this.name; }
                set
                {
                    if (this.name != value)
                    {
                        this.name = value;
                        RaisePropertyChanged("Name");
                    }
                }
            }
            private ObservableCollection<string> elements;
            public ObservableCollection<string> Elements
            {
                get { return this.elements; }
                set
                {
                    if (this.elements != value)
                    {
                        this.elements = value;
                        RaisePropertyChanged("Elements") ;
                    }
                }
            }
     
     
     
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged(String info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }
     
     
        }
    En respectant ce minimum tout devrait se passer normalement dans tes binding...

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Salut MABROUKI et Micka132,


    Merci pour vos réponses, je vais de suite faire ce que vous me conseillez.

    Je vous tiendrai au courant dans la journée de mon avancement.


    A bientôt

    Paibok

  18. #18
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Re-bonjour,


    J'ai fais tout ce que tu as indiqué MABROUKI mais malheureusement ça ne fonctionne pas .. Le fait d'enlever le override ToString fait que c'est le nom du "workspace + nomdemaclasse" qui s'affiche dans ma combobox ou dans mes listbox, je pense que je dois avoir un problème dans mon binding. Peut-être dois-je ajouté un path ?

    J'avoue que je suis nouveau en C#/.NET et meme si je m'en sors pas mal assez souvent il y a beaucoup de points importants que je ne maitrise pas du tout ..

  19. #19
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    Citation Envoyé par MABROUKI Voir le message
    7/NB : quand on fait un renommage de prop il ne faut pas oublier de mettre à jour le nom de prop ou string passé en paramètre du Handler RaisePropertyChanged
    Non pas avec la version du PropertyChanged qu'il utilise, à savoir l'utilisation de l'attribut CallerMemberName.


    Le fait d'enlever le override ToString fait que c'est le nom du "workspace + nomdemaclasse" qui s'affiche dans ma combobox ou dans mes listbox, je pense que je dois avoir un problème dans mon binding. Peut-être dois-je ajouté un path ?
    C'est bien ce que je pensais.
    Par défaut les contrôles de type itemcontrol (dont hérite listbox) affichent pour chaque élément le resultat de ToString(), qui par defaut en C# t'affiche le nom complet de ta classe (donc namespace+nom).
    Pour pallier à ça tu as redéfinis le ToString(), ce qui fonctionne très bien.
    Maintenant tu souhaites voir les modifications se répercuter.
    C'est seulement possible lorsque tu utilises le binding sur une propriété et que son changement de valeur est signalé via l'evenement PropertyChanged. Hors en utilisant le comportement par defaut de la listbox, à savoir utiliser le ToString(), tu n'as définis aucun binding, donc pas de mise à jour.
    La solution est donc de dire à ta listbox que tu veux comme affichage pour chacun des éléments qu'elle aille chercher la valeur de Name. Pour cela il faut redefinir l'itemtemplate comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding Name}"/> 
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>

  20. #20
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Juin 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Juin 2016
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par micka132 Voir le message
    Non pas avec la version du PropertyChanged qu'il utilise, à savoir l'utilisation de l'attribut CallerMemberName.
    Oui j'ai trouvé ça sur le site de MS.

    Quand je place ton code dans mon xaml il ne comprend pas le <ListBox.ItemTemplate> il le souligne en bleu ..

    A la base j'avais fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <ListBox x:Name="listLabels"
                             Grid.Row="5" 
                             HorizontalAlignment="Left" 
                             Height="130" 
                             VerticalAlignment="Top"
                             Width="180"
                             ItemsSource="{Binding SelectedItem.AssociatedLabels, ElementName=textToComboBox, Mode=TwoWay}" 
                             SelectionMode="Single"
                             />
    Car les élément affichés dans cette ListBox varies en fonction de la sélection de ma ComboBox.

Discussions similaires

  1. Suppression et modification de données dans une base Access depuis VB6
    Par sousousoumia dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 08/09/2012, 00h42
  2. Réponses: 6
    Dernier message: 07/07/2009, 15h06
  3. Réponses: 6
    Dernier message: 12/08/2007, 11h10
  4. Comment afficher un MessageBox depuis une fenêtre réduite ?
    Par cyberma dans le forum Composants VCL
    Réponses: 2
    Dernier message: 30/07/2005, 18h16
  5. Exportation de données depuis une base
    Par david71 dans le forum JBuilder
    Réponses: 2
    Dernier message: 22/06/2004, 10h31

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