简体   繁体   中英

Strange performance issue with WPF ComboBox binding

I have a performance issue that I just solved but I really don't understand why the solution works.

I have a ComboBox with about 4,000 items that I bind to a collection using the ItemSource property; if I bind to a property in the view-model with a getter and a setter everything works fine, but if I bind to a property with only a getter, the first time that I click on the combobox it works fine but everytime after that first time if I click on the combobox the application hangs for about 1 minute with the CPU for the process at ~100% before displaying the combo box items

View:

...
<ComboBox
    Grid.Column="1"
    ItemsSource="{Binding AvailableDispositionCodes}"
    DisplayMemberPath="DisplayName"
    SelectedItem="{Binding SelectedDispositionCode}"
    Width="Auto"
    Height="25"
    Margin="5 0 0 0">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
</ComboBox>
...

Working view-model:

...
private IEnumerable<DispositionCodeViewModel> availableDispositionCodes = new List<DispositionCodeViewModel>();
...
public IEnumerable<DispositionCodeViewModel> AvailableDispositionCodes
{
    get
    {
        return this.availableDispositionCodes;
    }

    set
    {
        this.availableDispositionCodes = value;
        this.OnPropertyChanged();
    }
}
...
public void Initialize()
{
    ...
    this.AvailableDispositionCodes = resultCodeViewModels.OrderBy(x => x.Name);
    ...
}
...

View-model that causes the application to hang:

...
private List<DispositionCodeViewModel> availableDispositionCodes = new List<DispositionCodeViewModel>();
...
public IEnumerable<DispositionCodeViewModel> AvailableDispositionCodes
{
    get { return this.availableDispositionCodes; }
}
...
public void Initialize()
{
    ...
    this.availableDispositionCodes.AddRange(resultCodeViewModels.OrderBy(x => x.Name));
    this.OnPropertyChanged(nameof(this.AvailableDispositionCodes));
    ...
}
...

The method Initialize of the view-model initializes the collection that is binded to the combobox and this method is called just once shortly after the view and the view-model are created. After that the collection doesn't change

Does anybody knows what causes this weird behavior?

I think it is about the List.AddRange() rather than the property.

If the new Count (the current Count plus the size of the collection) will be greater than Capacity, the capacity of the List is increased by automatically reallocating the internal array to accommodate the new elements, and the existing elements are copied to the new array before the new elements are added.

msdn

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM