2015-11-13 5 views
3

Я пытаюсь создать индекс, как показано на скриншоте ниже. Это было сделано простым добавлением программных texboxes в горизонтальные и вертикальные стековые панели внутри scrollviewer. Но это решение было невероятно медленным. Связывание заняло около 5 секунд.Создание индекса в C# WPF

enter image description here

Поэтому я проверил связать List<>, содержащий все данные непосредственно в ListBox. Я пробовал различные комбинации ItemTemplates, но даже с помощью VirtualizingPanel.IsVirtualizing="True" мне не удалось ускорить привязку. Лишь простой ListBox без каких-либо попыток группировки выполнил эту работу.

Это единственный XML-часть я использовал для всех моих тестов:

<StackPanel Orientation="Horizontal" Margin="0,0,0,5"> 
    <TextBlock Text="{Binding Name}" Style="{DynamicResource HoverUnderlineStyle}" MouseLeftButtonUp="..."> 
     <TextBlock.ContextMenu> 
      <ContextMenu> 
        <!-- ... --> 
      </ContextMenu> 
     </TextBlock.ContextMenu> 
    </TextBlock> 
    <TextBlock> 
     <TextBlock.Text> 
      <MultiBinding StringFormat=" ({0})"> 
       <Binding Path="Count"/> 
      </MultiBinding> 
     </TextBlock.Text> 
    </TextBlock> 
</StackPanel> 

Было бы очень здорово, если бы кто-то может помочь мне. Спасибо заранее!

+0

Какой контроль должен содержать текст? TextBlock или TextBox? (Вы написали TextBox, но на скриншоте они выглядят как текстовые блоки). И вы хотите, чтобы элементы были выбраны? – Snicker

+0

Извините за ошибку! TextBlock и да, элементы должны быть выбраны. – tron

+0

Каков фактический вопрос, вы просите о более эффективном решении? –

ответ

0

Я думаю, что должно работать: MainWindow.xaml

<Window.DataContext> 
    <local:MainViewModel /> 
</Window.DataContext> 
<Grid> 
    <ListBox DisplayMemberPath="Value" 
      ItemsSource="{Binding CollectionView}" 
      ScrollViewer.HorizontalScrollBarVisibility="Visible" 
      ScrollViewer.VerticalScrollBarVisibility="Visible"> 
     <ListBox.GroupStyle> 
      <GroupStyle> 
       <GroupStyle.HeaderTemplate> 
        <DataTemplate> 
         <TextBlock FontWeight="Bold" Text="{Binding Name}" /> 
        </DataTemplate> 
       </GroupStyle.HeaderTemplate> 
       <GroupStyle.Panel> 
        <ItemsPanelTemplate> 
         <WrapPanel /> 
        </ItemsPanelTemplate> 
       </GroupStyle.Panel> 
      </GroupStyle> 
     </ListBox.GroupStyle> 
    </ListBox> 
</Grid> 

ViewModel:

class MainViewModel 
{ 
    private static readonly Random Random = new Random(); 

    public MainViewModel() 
    { 
     var list = new List<string>(); 
     for (int i = 0; i < 2000; i++) 
     { 
      list.Add(RandomString(8)); 
     } 

     CollectionView = 
      CollectionViewSource.GetDefaultView(list.OrderBy(x => x[0]).Select(x => new TestItem {Value = x})); 
     CollectionView.GroupDescriptions.Add(new PropertyGroupDescription("Value", new FirstLetterConverter())); 
    } 

    public ICollectionView CollectionView { get; set; } 

    public static string RandomString(int length) 
    { 
     const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
     return new string(Enumerable.Repeat(chars, length) 
      .Select(s => s[Random.Next(s.Length)]).ToArray()); 
    } 
} 

public class TestItem 
{ 
    public string Value { get; set; } 
} 

public class FirstLetterConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     string s = value as string; 
     if (!string.IsNullOrEmpty(s)) 
      return s.Substring(0, 1); 
     return string.Empty; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

Если это замедлить для вас, вы можете искать оберточной панель, которая поддерживает виртуализацию, потому что который не поддерживается инфраструктурой .net.

Preview: Preview

+0

Спасибо за ваш андерсер. Я проверю это. – tron

0

Не видя остальную часть кода, я могу указать на несколько улучшений к вашему Xaml:

  1. Попробуйте использовать StaticResource вместо DynamicResource.
  2. Вам не нужен MultiBinding во втором текстовом блоке. Фактически, вы можете использовать один TextBlock с несколькими Run s и избавиться от StackPanel.
<TextBlock Style="{StaticResource HoverUnderlineStyle}" MouseLeftButtonUp="..."> 
    ... 
    <Run Text="{Binding Name}"/> 
    <Run Text="{Binding Count, StringFormat={} ({0})}"/> 
</TextBlock> 
Смежные вопросы