programing

많은 컬렉션을 바인딩하여 WPF ComboBox 성능 문제

instargram 2023. 5. 27. 09:38
반응형

많은 컬렉션을 바인딩하여 WPF ComboBox 성능 문제

많은 컬렉션을 ComboBox에 바인딩하려고 하는데 ComboBox 팝업을 열 때 성능 문제가 발생했습니다.인터넷을 검색해 보니 가상화 스택 패널을 항목 패널 템플릿으로 사용하는 것이 도움이 될 수 있지만 부분적으로만 도움이 되었습니다.많은 컬렉션을 ComboBox에 바인딩하면 팝업을 매우 빠르게 열 수 있지만, 그런 다음 다른 컬렉션을 ComboBox에 바인딩하고 다시 팝업을 열려고 하면 속도가 매우 느려집니다.빈 ComboBox에 대한 팝업을 연 다음 큰 컬렉션을 바인딩하고 팝업을 다시 열려고 할 때도 마찬가지입니다. 팝업이 열리기까지 몇 초 정도 걸립니다.

XAML은 다음과 같습니다.

<ComboBox Name="cbBlah">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
</ComboBox>

문제를 재현하기 위한 바인딩 샘플 코드:

var list = new List<string>();
for (var i = 0; i < new Random().Next(9000, 10000); i++)
    list.Add(i.ToString());
cbBlah.ItemsSource = list;

가상화 스택 패널을 다음과 같이 구성하려고 했습니다.

<VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" />

그러나 가상화 모드가 무시되는 것처럼 보이므로 처음에만 팝업이 매우 빠르게 열리고 바인딩이 변경될 때마다 속도가 매우 느려집니다.

업데이트: 매번 새 컬렉션을 바인딩하지 않고 관찰 가능한 컬렉션을 한 번 바인딩한 다음 내용만 변경하는 방법을 생각했습니다.마찬가지로 수집 내용이 변경되는 즉시 팝업을 여는 데 몇 초가 걸립니다.

이 블로그에 따르면: http://vbcity.com/blogs/xtab/archive/2009/12/15/wpf-using-a-virtualizingstackpanel-to-improve-combobox-performance.aspx

다음 코드로 테스트했습니다.

<ComboBox Name="cbBlah" ItemsSource="{Binding}">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
</ComboBox>

처음과 다음 번에는 잘 작동합니다.다음 행을 코딩할 필요가 없습니다.

<VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" />

저는 느린 성능에도 문제가 있었습니다.하지만 콤보박스 형태를 이어받은 클래스를 만들어서 프로그래밍 방식으로 하고 싶습니다.여기 다른 구글 사용자들을 위한 해결책이 있습니다.

ItemsPanel = new ItemsPanelTemplate();
var stackPanelTemplate = new FrameworkElementFactory(typeof (VirtualizingStackPanel));
ItemsPanel.VisualTree = stackPanelTemplate;

저도 방금 이 문제에 부딪혔습니다.스타일 템플릿이 있는 사용자 지정 콤보 상자에서 이 코드를 사용하고 있습니다.VS 디버깅 모드에서 코드를 실행했을 때 가상화가 제대로 작동하지 않았습니다.디버깅을 벗어나 실행하면 UI를 잠그지 않고 관찰 가능한 컬렉션의 내용을 전환할 수 있습니다.최대 높이와 최대 너비를 설정하는 경우에도 도움이 될 수 있습니다.

<Setter Property="ScrollViewer.CanContentScroll" Value="True"/> 
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Popup>
    <Border/>
    <ScrollViewer>
      <VirtualizingStackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
    </ScrollViewer> 
  </Grid>
</Popup>

사용 편의성 측면에서 볼 때, 화면에 들어갈 수 있는 것보다 많은 항목이 있는 표준 콤보 상자를 사용하는 것은 항상 번거롭습니다.텍스트 상자 필터 이상이 필요합니다.대부분의 경우 옵션은 미리 필터링할 수 있으며(예: 부서별, 첫 글자 또는 범위별) 객체를 적게 생성하고 일반적으로 사용자에게 더 친숙합니다.

언급URL : https://stackoverflow.com/questions/8198645/wpf-combobox-performance-problems-by-binding-a-large-collections

반응형