2010-10-29 3 views
3

Как скрыть ListViewItem в связанном ListView? Примечание. Я не хочу его удалять.Скрыть ListViewItem в WPF ListView

+0

Скрыть это навсегда? Или это после какого-то действия? Больше деталей было бы хорошо ... –

+0

Его потому что я имею listview bbinded к списку. если я хочу удалить элемент из списка, мне нужно удалить его в списке. поэтому я этого не хотел. я думаю, лучше всего просто скрыть это. – shinji14

+1

Не забудьте отметить правильный ответ. –

ответ

3

Используйте стиль с триггером, чтобы установить видимость элементов на рулон.

+0

У вас есть пример, пожалуйста? – shinji14

+0

Может быть, вы должны использовать DataTrigger –

1
<ItemsControl> 
<ItemTemplate> 
    <DataTemplate> 
    <Image Visibility='{Binding Converter=my:MaybeHideThisElementConverter}' /> 
    </Image> 
    </DataTemplate> 
</ItemTemplate> 
</ItemsControl> 

Что мы здесь делаем, это делегирование решения вашей реализации MaybeHideThisElementConverter. Здесь вы можете вернуть Collapsed, если свойство User вашего объекта равно NULL, или если Count является четным числом или любой другой пользовательской логикой, требуемой вашим приложением. Конвертер будет передан каждому элементу в вашей коллекции один за другим, и вы можете вернуть либо Visibility.Collapsed, либо Visibility.Visible в каждом отдельном случае.

9

Да, это легко.

Первое, что вам нужно сделать, это добавить свойство к классу, к которому вы привязываетесь. Например, если вы привязываетесь к классу User с FirstName и LastName, просто добавьте свойство Boolean IsSupposedToShow (вы можете использовать любое свойство, которое вам нравится, конечно). Примерно так:

class User: INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    private bool m_IsSupposedToShow; 
    public bool IsSupposedToShow 
    { 
     get { return m_IsSupposedToShow; } 
     set 
     { 
      if (m_IsSupposedToShow == value) 
       return; 
      m_IsSupposedToShow = value; 
      if (PropertyChanged != null) 
       PropertyChanged(this, 
        new PropertyChangedEventArgs("IsSupposedToShow")); 
     } 
    } 
} 

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

Как это:

<DataTemplate DataType="{x:Type YourType}"> 
    <DataTemplate.Resources> 
     <Style TargetType="{x:Type TextBlock}"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding IsSupposedToShow}" Value="False"> 
        <Setter Property="Visibility" Value="Collapsed"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </DataTemplate.Resources> 
    <!-- your UI here --> 
    <TextBlock> 
     <TextBlock.Text> 
     <MultiBinding StringFormat="{}{0}, {1}"> 
      <Binding Path="LastName" /> 
      <Binding Path="FirstName" /> 
     </MultiBinding> 
     </TextBlock.Text> 
    </TextBlock> 
</DataTemplate> 

При изменении IsSupposedToShow ложь, то XAML понимает, что должен изменить видимость всей DataTemplate. Это все связано с WPF и presto, это то, что вы хотели в своем вопросе!

Удачи!

+0

Это не будет работать динамически, если вы не внедрили 'INotifyPropertyChanged' в класс' User' и не подменили 'PropertyChange', когда изменяется' IsSupposedToShow'. (Также я бы назвал это свойство 'IsVisible'.) –

+0

@Robert Rossney, Welp: S Вы правы. Я обновил код, чтобы отразить вашу точку зрения. Я действительно не пытался писать готовые продукты, но было просто добавить к побочному шагу следующий вопрос. Хороший улов. –

+2

Я чувствую, что что-то пропустил. XAML делает текст элемента равным нулю, но не элемент в списке. –

1

подходы, которые я бы следовать, от большинства наименее предпочтительным:

  • В ListView.ItemContainerStyle используйте DataTrigger установить Visibility на основе связанного имущества.
  • Используйте стиль в ItemTemplate или в DataTemplate для элементов, если вы получаете шаблоны по умолчанию из словаря ресурсов.
  • Установите ItemsSource на ListView на номер CollectionView и обработайте событие CollectionViewFilter в кодовом замке. См. MSDN's discussion of collection views.
  • Поддержание отдельного ObservableCollection в качестве ItemsSource для ListView и добавления/удаления элементов, если необходимо.

Ни при каких обстоятельствах я не использовал бы ValueConverter, потому что у меня есть возможное иррациональное отвращение к ним.

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

+0

Почему триггер стиля в DataTemplate не сделал ваш список? Это самый простой подход. –

+1

Он сделал! Это второй пункт. Я предпочитаю использовать 'ItemContainerStyle' по умолчанию. Это так же просто, и это также означает, что поведение локализовано в «ListView». Это может быть важным отличием, когда 'DataTemplate' не определяется локально в' ListView'. –

+0

Да, я вижу вашу точку зрения и соглашаюсь. Но стиль, определенный в datatemplate для itemtemplate, также является локальным, чтобы выбрать nits. Но если файл данных вставляется в «Ресурсы», то у вас есть очень действительная точка. –

1

Эта страница предоставила мне ответ мне необходимый: http://www.abhisheksur.com/2010/08/woring-with-icollectionviewsource-in.html (См. Раздел «Фильтрация».)

Ничего себе, гораздо проще, чем XAML.

Пример:

bool myFilter(object obj) 
{ 
    // Param 'obj' comes from your ObservableCollection<T>. 
    MyClass c = obj as MyClass; 
    return c.MyFilterTest(); 
} 

// apply it 
myListView.Items.Filter = myFilter; 
// clear it 
myListView.Items.Filter = null; 
Смежные вопросы