Не показывать элементы с видимостью = Свернуто в Windows 8.1 GridView
У меня есть приложение Windows 8.1 с GridView
, связанное с пользовательской (сортируемой, дедуплицируемой) наблюдаемой коллекцией. В этой коллекции я делаю тяжелую фильтрацию и устанавливаю флаг IsHidden для каждого элемента.
В шаблоне данных для элемента есть условие, делающее элемент свернутым, если флаг 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 заключается в том, что когда я устанавливаю элемент в коллекции скрытым, id исчезает из GridView
, но оставляет пустое место, поэтому в GridView
есть пробел.
![enter image description here]()
Любые идеи о том, как его решить? Может быть, такое же редактирование стиля XAML?
Вот минимальное решение для воспроизведения проблемы: https://dl.dropboxusercontent.com/u/73642/gv.zip
Я попытался привязать ширину и высоту элементов к скрытому флагу и установить его на 0, когда элемент скрыт, но это не помогло, все еще пробел в GridView
.
Обновить. Один способ обхода - это фильтрация фактической привязки, но это невозможно из-за некоторых бизнес-требований.
Ответы
Ответ 1
Проблема заключается в GridView
ItemsPanel
.
Оба ItemsWrapGrid
и WrapGrid
являются равномерными сетками. Все их дочерние элементы будут иметь одинаковую высоту и ширину. Вот почему, даже если вы сбрасываете ItemTemplate
, пространство по-прежнему сохраняется.
Что вам действительно нужно, это WrapPanel
. WINRT не имеет встроенного WrapPanel
, но Джерри Никсон построил его, и вы можете его захватить из здесь.
После того, как вы обновили свой 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;
}
Я поставил немного задержку выше, чтобы сделать коллапс более очевидным.
Ответ 2
Я попробовал ваше тестовое решение и вместо этого заменил его на ListView. Он проявляет такое же поведение, когда сама сетка скрыта. У меня нет XAML Spy для проверки, но похоже, что любой элемент управления, основанный на списке, будет выделять отображаемый элемент для каждого элемента в списке.
Я изменил ваш клик-дескриптор вместо ds.RemoveAt(5);
вместо того, чтобы скрывать элемент, и элемент удаляется из представления с помощью хорошей анимации. Это кажется ожидаемым, и интересная находка.
Ответ 3
Мне нужно много времени, чтобы понять проблему, и решение прямо перед моими глазами. Вы пытаетесь скрыть сам элемент, но контейнер все еще там. Когда вы добавляете элемент в GridView, элемент обернут в контейнер товаров. из msdn:
"Когда вы добавляете элемент в элемент управления ItemsControl, элемент завернут в контейнер предметов. Например, элемент, добавленный в ListView, завернут в ListViewItem. Без виртуализации пользовательского интерфейса весь набор данных сохраняется в памяти и контейнер элементов также создается для каждого элемента в набор данных. ListView, связанный с коллекцией из 1000 элементов, будет также создайте 1000 контейнеров ListViewItem, которые хранятся в памяти."
Вам нужно отключить контейнер и создать два DataTemplate, а с помощью DataTemplateSelector вы можете выбрать, какой DataTemplate можно отключить и активировать. Проверьте эту полезную статью.