1 votes

Mise à jour des contrôles liés aux ApplicationSettings

Je tente d'utiliser la fonctionnalité ApplicationSettings de .NET 2.0 pour la première fois et je la trouve un peu... déroutante à certains égards. J'espère que quelqu'un pourra m'aider à comprendre où je me trompe.

J'ai une classe de paramètres génériques que j'ai implémentée qui est une sous-classe de ApplicationSettingsBase. J'ai implémenté une propriété et je l'ai taguée. Cela semble fonctionner.

J'ai ensuite essayé de lier un contrôle listbox à la propriété, et cela semble également fonctionner. Lorsque j'ouvre le formulaire, il charge correctement les propriétés.

Le problème auquel je suis confronté est que si je veux mettre à jour les paramètres et le data binding sans recharger le formulaire, cela ne semble pas fonctionner. Il n'y a pas de méthodes pour rafraîchir la liaison, et d'après ce que je lis, cela devrait se mettre à jour automatiquement (ApplicationSettingsBase implémente IPropertyChangeNotify, auquel les DataBindings devraient s'abonner... mais cela ne semble pas fonctionner). Vous ne pouvez pas non plus mettre à jour manuellement le listbox si vous avez un DataBinding.

Voici mon code :

Settings.cs

public class Settings : ApplicationSettingsBase
{
    public Settings()
    {
        if (FixedBooks == null) FixedBooks = new List();
    }

    [UserScopedSetting()]
    public List FixedBooks
    {
        get { return (List)this["FixedBooks"]; }
        protected set { this["FixedBooks"] = value; }
    }
}

SettingsForm.cs

Settings _settings = new Settings();

private void SettingsForm_Load(object sender, EventArgs e)
{
    lbFixedColumns.DataBindings.Add(new Binding("DataSource", _settings,
        "FixedBooks", false, DataSourceUpdateMode.OnPropertyChanged));
}

private void DoSomething()
{
    _settings.FixedBooks.Add("Test");
}

De ce que je comprends, ajouter quelque chose aux ApplicationSettings devrait déclencher IPropertyChangedNotify pour avertir le contrôle de liaison que la propriété a changé et le forcer à se recharger... mais cela ne semble pas se produire.

Qu'est-ce que j'ai oublié ?

EDIT:

Je crois savoir quel est le problème. Le problème est que je modifie le contenu de la collection dans la classe Settings, mais je ne change pas la propriété elle-même (qui est la collection elle-même). Je pense que je devrais réellement ajouter ou supprimer l'ensemble de la collection pour que IPropertyChangedNotify se déclenche, ce qui ne se produit pas.

Je ne suis pas sûr de quelle est la solution à ce problème.

1voto

drs9222 Points 1786

Vous devez enregistrer le paramètre et le recharger :

private void DoSomething()
{
    _settings.FixedBooks.Add("Test");
    _settings.Save();
    _settings.Reload();
}

Je suis d'accord avec votre modification et votre commentaire. Essayez d'utiliser une BindingList à la place.

Exemple :

public class Settings : ApplicationSettingsBase
{
    public Settings()
    {
        if (FixedBooks == null) FixedBooks = new BindingList();
        FixedBooks.ListChanged += FixedBooks_ListChanged;
    }

    void FixedBooks_ListChanged(object sender, ListChangedEventArgs e)
    {
        this["FixedBooks"] = FixedBooks;
    }

    [UserScopedSetting()]
    public BindingList FixedBooks
    {
        get { return (BindingList)this["FixedBooks"]; }
        protected set { this["FixedBooks"] = value; }
    }
}

0voto

Erik Funkenbusch Points 53436

D'accord, ce n'est pas une solution géniale, et j'espère que quelqu'un en aura une meilleure, mais cela fonctionne :

private void DoSomething()
{
    _settings.FixedBooks.Add("Test");    
    var old = _settings.FixedBooks;
    _settings["FixedBooks"] = new List();
    _settings["FixedBooks"] = old;
}

J'ai essayé de simplement réassigner la liste à elle-même, mais il semble qu'il y ait une optimisation qui détecte cela et ne déclenche pas le PropertyChanged.

Je serais plus qu'heureux de donner une réponse à quelqu'un qui trouve une meilleure solution.

MODIFIER :

D'accord, je pense avoir trouvé une solution acceptable qui est juste un peu bricolée, et ne nécessite pas la création de nouveaux objets comme ci-dessus sans raison.

D'accord, tout d'abord, j'ajoute une nouvelle méthode à ma classe Paramètres :

public void FirePropertyChanged(string propertyName)
{
    PropertyChangedEventArgs args2 = new PropertyChangedEventArgs(propertyName);
    OnPropertyChanged(this, args2);
}

Cela me permet de déclencher un événement PropertyChanged sans réellement changer la propriété. Cependant, la classe Binding est encore un peu trop intelligente pour moi, car elle sait que la propriété n'a pas vraiment changé... donc elle ne fait rien.

private void DoSomething()
{
    _settings.FixedBooks.Add("Test");
    lbFixedColumns.DataSource = null;
    _settings.FirePropertyChanged("FixedBooks");
}

Donc, ce code trompe la classe Binding, en effaçant la DataSource elle ne peut plus dire que la propriété n'a pas changé, donc elle doit récupérer la dernière version des données. Je peux vivre avec cela, même si c'est encore un peu bancal.

MODIFIER2 :

Comme drs le souligne, j'aurais dû utiliser une BindingList plutôt qu'une List, utiliser une BindingList est la solution correcte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X