2014-12-02 2 views
10

У меня есть приложение Windows 8.1 с GridView, связанное с пользовательской (сортируемой, дедуплицируемой) наблюдаемой коллекцией. В этой коллекции я делаю тяжелую фильтрацию и устанавливаю флаг IsHidden для каждого элемента.Не показывать элементы с видимостью = Свернуто в Windows 8.1 GridView

В шаблоне данных для элемента есть условие, делающее элемент свернутым, если установлен флаг IsHidden для true.

<Grid Width="160" Height="280" Visibility="{Binding IsHidden, Converter={StaticResource InvertedBooleanToVisibilityConverter}}"> 

Этот подход работает в Windows Phone 8.1 XAML, что делает элементы исчезают из ListView, но он не работает в ОС Windows 8.1 GridView. Проблема с Windows 8.1 заключается в том, что когда я устанавливаю элемент в коллекции для скрытия, идентификатор исчезает с GridView, но оставляет пустое место, поэтому в GridView есть пробел.

enter image description here

Любые идеи о том, как решить эту проблему? Может быть, такое же редактирование стиля XAML?

Здесь минимальное решение для воспроизведения проблемы: https://dl.dropboxusercontent.com/u/73642/gv.zip

Я попытался связывание ширины и высоты элементов для скрытого флага и установить его в 0, когда элемент скрыт, но это не помогло, до сих пор зазор в GridView.

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

+0

Вы уверены, что это 'Visibility.Collapsed'? Потому что он выглядит как «Visibility.Hidden» (и вы точно знаете [разницу] (http://stackoverflow.com/q/886742/1997232)). – Sinatr

+0

Да, я уверен, нет видимости. Скрыто в winrt –

+0

Что вы используете в качестве своей GridView.ItemsPanel? –

ответ

5

Проблема в GridViewItemsPanel.

Оба ItemsWrapGrid и WrapGrid являются равномерными сетками.Все их дочерние элементы будут иметь одинаковую высоту и ширину. Вот почему, даже если вы рухнете ItemTemplate, пространство по-прежнему сохраняется.

Что вам действительно нужно, это WrapPanel. WINRT не имеет встроенного WrapPanel, но Джерри Никсон построил один, и вы можете его захватить с here.

После того, как вы обновили GridView с ItemsPanel, у вас все еще есть еще одна вещь. Вы также должны получить GridViewItem, где размещены ваши Itemtemplate, и установите его Visibility на номер Collapsed.

private async void Button_Click(object sender, RoutedEventArgs e) 
    { 
     ds[5].IsHidden = true; 

     await Task.Delay(1000); 
     var gridViewItem =(GridViewItem)this.gv.ContainerFromIndex(5); 
     gridViewItem.Visibility = Visibility.Collapsed; 
    } 

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

+1

Спасибо, что предоставил мне кредит на 'WrapPanel'. Вы отлично справились с этой проблемой. Мне кажется, что удаление его из «ObservableCollection » предоставило бы ему все, что он хотел, без всякой кодирующей гимнастики; но я видел его комментарий об этом. –

+0

Вы заслуживаете кредит @ JerryNixon-MSFT, иначе я даже не смог бы ответить на него! :) –

0

Я попробовал ваше решение для образца и вместо этого заменил его на ListView. Он проявляет такое же поведение, когда сама сетка скрыта. У меня нет XAML Spy для проверки, но кажется, что любой элемент управления, основанный на списке, будет выделять отображаемый элемент для каждого элемента в списке.

Вместо этого я сменил свой рабочий стол, а не ds.RemoveAt(5); вместо того, чтобы скрывать элемент, и элемент удаляется из представления с помощью приятной анимации. Это похоже на то, как ожидалось, и на интересную находку.

+0

см. Мое обновление .. –

0

Мне нужно много времени, чтобы понять проблему, и решение прямо перед моими глазами. Вы пытаетесь скрыть сам элемент, но контейнер все еще там. Когда вы добавляете элемент в GridView, элемент обернут в контейнер товаров. Из MSDN:

"При добавлении элемента к ItemsControl, элемент обернут в контейнере пункта Например, элемент, добавленный к ListView обернута в ListViewItem без виртуализации пользовательского интерфейса, то.. полный набор данных сохраняется в памяти и контейнер элементов также создается для каждого элемента в наборе данных . ListView, связанный с коллекцией из 1000 элементов, будет также создавать 1000 контейнеров ListViewItem, которые хранятся в памяти. "

Вам необходимо отключить контейнер и создать два DataTemplate, а с помощью DataTemplateSelector вы можете выбрать, какой DataTemplate можно отключить и активировать. Check this useful article.

Смежные вопросы