Первый элемент в ListView с привязкой к данным иногда дублируется? - PullRequest
0 голосов
/ 31 октября 2010

У меня есть WPF (.Net 4) ListView, используемый для навигации по локальному каталогу Windows. Он отображает содержимое текущего каталога, с именем и размером и все такое. Однако в некоторых каталогах первый отображаемый элемент отображается дважды. Например, допустим, в каталоге «D1» у меня есть подкаталоги «W», «X», «Y» и «Z». ListView скажет «W W X Y Z», даже если фактические данные, к которым он привязан (a ThreadObservableCollection ), не имеют дубликата. ThreadObservableCollection также изначально пуст, когда создается объект, который его содержит, подкаталоги и файлы находятся в фоновом потоке, а затем помещаются в коллекцию по мере их нахождения.

Я в недоумении, как даже отладить это, поскольку это происходит исключительно в области представления, и я боюсь, что это может быть ошибкой в ​​самой платформе. Это происходит не в каждом каталоге, но кажется (несколько) повторяемым в тех, в которых оно встречается, что говорит о том, что здесь есть какой-то шаблон, хотя мне еще предстоит найти какие-либо отличительные характеристики. Это также всегда первая запись, если это произойдет.

Я также попытался прослушать событие CollectionChanged в ThreadObservableCollection, но оно срабатывает только один раз для каждого элемента, измененного, как и следовало ожидать, и я наблюдал за предоставленными значениями, чтобы убедиться, что нет дубликатов (которых нет ).

Я также прикрепил DebugConverter (см. Ниже) к TextBlock, содержащему имя показанных (под) каталогов, и он действительно показывает повторяющиеся значения. Так что в ListView определенно есть две фактические строки с одним и тем же элементом позади них, но я до сих пор не знаю, почему.

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

1 Ответ

1 голос
/ 31 октября 2010

Я бы, вероятно, начал с его запуска через DebugConverter (вам придется написать его, я не думаю, что есть реализация, опубликованная с .Net). Это выглядит так:

(Очевидно, прикрепите точку останова в VS к одной строке кода в методе).

 public class DebugConverter : IValueConverter { 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      return value;    
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

Теперь вы можете вставить точку останова и убедиться, что дубликат действительно обнаруживается на уровне генерации интерфейса. Изучите абсолютный путь к файлу (это, например, "." По умолчанию, который представляет текущий каталог, или что-то в этом роде? Это неправильное преобразование где-то еще? Я не знаю, почему это произойдет только в некоторых каталогах , но начните с широкого использования вашей сети отладки).

Вероятно, это не проблема с многопоточностью, потому что, на мой взгляд, Диспетчер контролирует все взаимодействия с пользовательским интерфейсом, включая наблюдаемую коллекцию, которая поддерживает ваше представление, что означает, что он может взаимодействовать только последовательно. Однако, если вы не используете ObservableCollection, возможно, у вас есть потоки? Я подозреваю, что WPF довольно строго относится к любому вспомогательному перечислению, но я не уверен. Ой, подождите, вы сказали, что используете ObservableCollection. Хорошо, не может быть нить Вы делаете что-нибудь модное с DataTemplateSelector? Есть ли стиль, который применяет шаблон представления? Могли бы вы иметь и Сеттер по умолчанию, применяющий стиль, и Триггер, включающий другой элемент просмотра?

Давайте постараемся изо всех сил, чтобы не предполагать, что это ошибка в фреймворке. По моему опыту, проблема ВСЕГДА в моем коде, даже если я не чувствую, что он может быть заранее.

(оставить комментарий)

Даже если ваша коллекция была пустой на момент привязки, вы сможете получить доступ к отдельным элементам, когда они входят вот так:

<ListView>
 <ListView.ItemTemplate>
  <DataTemplate>
   <TextBlock Text='{Binding Path=filename, Converter={StaticResource DebugConverter}' />
  ...etc
  </DataTemplate>
 </ListView.ItemTemplate>
</ListView>

Есть ли шанс опубликовать свой код?

...