2010-11-24 28 views
1

Étapes de réexpédition:Pourquoi ma liste déroulante se fige-t-elle lorsque la source d'articles change? Lorsque l'application démarre, ouvrez la liste déroulante afin que les éléments soient générés.

Maintenant, cliquez sur le "Click Me!" bouton. Dans le code derrière, la source d'éléments de la liste déroulante est modifiée. Maintenant, essayez d'ouvrir à nouveau la liste déroulante. La liste déroulante se fige pendant au moins 5 secondes même si seulement 2 éléments sont dans la collection liée. Ceci est juste une application de test. Dans ma vraie application, il y a plus de 2 items et le décalage est insupportable. J'ai essayé ceci avec la virtualisation on et off. Ça ne fait aucune différence.

Qu'est-ce qui prend tellement de temps? Comment puis-je réparer ça? S'il n'y a pas de solution directe, y a-t-il un travail?

XAML:

<StackPanel> 
     <ComboBox x:Name="cbo" DisplayMemberPath="Junk1"></ComboBox> 
     <Button Content="Click Me!" Click="btn_Click"></Button> 
    </StackPanel> 

CODE:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Loaded += new RoutedEventHandler(MainWindow_Loaded); 
    } 

    ObservableCollection<Junk> junk1 = new ObservableCollection<Junk>() { 
     new Junk() { Junk1 = "jdkf", Junk2 = "fjdfkasjd;klfj" }, 
     new Junk() { Junk1 = "jfdk;a", Junk2 = "fjkdljf" } }; 

    ObservableCollection<Junk> junk2 = new ObservableCollection<Junk>() { 
     new Junk() { Junk1 = "fjkdfhsdjk", Junk2 = "fdjkah;" }, 
     new Junk() { Junk1="", Junk2 = "asdfj" } }; 

    void MainWindow_Loaded(object sender, RoutedEventArgs e) 
    { 
     this.cbo.ItemsSource = junk1; 
    } 

    private void btn_Click(object sender, RoutedEventArgs e) 
    { 
     if (this.cbo.ItemsSource == junk1) 
      this.cbo.ItemsSource = junk2; 
     else 
      this.cbo.ItemsSource = junk1; 
     this.cbo.UpdateLayout(); 
    } 
} 

public class Junk 
{ 
    public string Junk1 { get; set; } 
    public string Junk2 { get; set; } 
} 
+0

Avez-vous d'autres événements qui pourraient être licencient lorsque vous cliquez sur ce combobox (pas lorsque vous chargez)? –

+0

Pourquoi modifiez-vous ItemsSource plutôt que de simplement changer les éléments dans ObservableCollection lui-même? En outre Junk ne dérive pas de toute représentation de l'interface utilisateur correcte? C'est juste un cours standard? –

+0

Je ne parviens pas à reproduire ce problème dans Silverlight. – AnthonyWJones

Répondre

0

myermian - Aucun autre événement sont câblés. C'est l'application entière. Il n'y a pas d'autre code requis pour obtenir le comportement de congélation.

Aaron - Junk est juste une classe standard. Cela ne dérive de rien. J'ai essayé de conserver la collection, en appelant la méthode .Clear() et en ajoutant les nouveaux éléments. J'ai exactement le même comportement.

AnthonyWJones - Le bogue est dans WPF. Je ne l'avais pas essayé dans Silverlight. Désolé pour la confusion.

0

J'ai copié votre code exactement, et il fonctionne parfaitement comme prévu - donc je suggère qu'il peut y avoir quelque chose de mal dans votre environnement.

Remarque: vous n'avez pas besoin d'appeler this.cbo.UpdateLayout(); car ItemsSource est une propriété de dépendance et mettra à jour le contrôle automatiquement lorsqu'il est modifié.

+0

Vous n'avez pas eu de congélation? Avez-vous déposé la liste déroulante pour générer les conteneurs d'éléments avant d'appuyer sur le bouton? J'ai le même comportement sur deux machines différentes. Les deux machines sont à jour avec .NET 4.0 et VS2010. –

1

On dirait que cela est causé par des tonnes d'exceptions de première chance d'être traitées par le débogueur. Une explication plus longue est sur le MS forums, voir la réponse acceptée. La même construction ne montre aucun retard notable si elle est exécutée séparément.