绑定ListViewItem的可见性

时间:2015-05-08 22:45:41

标签: c# xaml listview winrt-xaml

我正在开发适用于Windows Phone 8.1的应用程序。在该应用程序中,我想将ObservableCollection<DisruptionDisplayElement>的项目绑定到ListViewDisruptionDisplayElement有一个名为bool IsFavorite的媒体资源。在ListView中,我想要隐藏IsFavorite为假的所有项目。 如果我使用ItemContainerStyle并使用转换器将Visibility - 属性设置为折叠,那么我就无法使用它。如果我以相同的方式定义Backgroundcolor进行测试,它就可以工作。 我也可以隐藏网格,其中ListViewItem的所有内容都在其中,但在这种情况下,我仍然拥有ListViewItem的装饰,占用大约50个像素的空间。

这就是我所拥有的:

XAML:

<Page
    x:Class="myApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:myApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:converter="using:myApp.Converter"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    >
    <Page.Resources>            
        <converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConv"/>
    </Page.Resources>
    <Grid>
        <Hub Header="{Binding CityName}" 
             SectionsInViewChanged="Hub_SectionsInViewChanged" 
             Grid.Row="1"
             >
             <HubSection Header="My Lines" Name="hubFavorites">
                 <DataTemplate>
                     <Grid Margin="0,-25,0,0">
                         <ListView 
                             ItemsSource="{Binding DisruptionDisplayList}"
                             Grid.Row="1"
                             >
                             <ListView.ItemContainerStyle>
                         <Style TargetType="ListViewItem">
                                     <!-- This seems not to work -->
                                     <Setter Property="Visibility" Value="{Binding IsFavorite, Converter={StaticResource BoolToVisibilityConv}}"/>
                                     <!-- For testing -->
                                     <Setter Property="Background" Value="Aqua"/>
                                 </Style>
                             </ListView.ItemContainerStyle>
                             <ListView.ItemTemplate>
                                 <DataTemplate>
                                     <!-- The Visibility-Property is just for testing as described -->
                                     <Grid 
                                         Margin="0,0,0,10" 
                                         Visibility="{Binding IsFavorite, Converter={StaticResource BoolToVisibilityConv}}"
                                         >
                                         <!-- Content here -->
                                         <TextBlock Text="{Binding Message}"/>
                                      </Grid>
                                 </DataTemplate>
                              </ListView.ItemTemplate>
                         </ListView>
                     </Grid>
                </DataTemplate>
            </HubSection>
        </Hub>
    </Grid>
</Page>

转换器:

namespace myApp.Converter
{
    public class BoolToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string culture)
        {
            return (bool) value ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string culture)
        {
            throw new NotImplementedException();
        }
    }
}

DisruptionDisplayElement:

public class DisruptionDisplayElement
{
    public string Message { get; set; }

    public bool IsFavorite { get; set; }
}

代码背后:

namespace myApp
{
    public sealed partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();

            DataContext = new ViewModel;
        }
    }
}

我的“ViewModel” - 类:

namespace myApp
{
    public class ViewModel
    {
        public ObserverableCollection<DisruptionDisplayElement> DisruptionDisplayList {get;set;}

        public ViewModel()
        {
            DisruptionDisplayList = new ObservableCollection<DisruptionDisplayElement>();
            DisruptionDisplayList.Add(new DisruptionDisplayElement() { IsFavorite = true, Message = "Message 1"});
            DisruptionDisplayList.Add(new DisruptionDisplayElement() { IsFavorite = false, Message = "Message 2" });
            DisruptionDisplayList.Add(new DisruptionDisplayElement() { IsFavorite = true, Message = "Message 3" });
        }
    }
}

如果我隐藏网格里面的网格,我该怎么做才能隐藏ListViewItem而不浪费emtpy ListViewItems的所有空间?

修改 高级代码提供

2 个答案:

答案 0 :(得分:0)

如果没有a good, minimal, complete code example,则无法提供在您的确切方案中显示正确技术的实际代码示例。

但是,基本答案是您应该使用ICollectionView根据某些属性过滤视觉呈现。

有很多方法可以做到这一点。最简单的方法之一是将过滤应用于数据源的默认视图。这样的视图总是存在,如果您只是将数据源绑定到单个可视对象,或者您希望以相同方式过滤呈现该数据源的所有可视对象,那么获取和修改此视图是正确的方法

举个例子:

ICollectionView view = CollectionViewSource.GetDefaultView(DisruptionDisplayList);

view.Filter = item => ((MyClass)item).IsFavorite;

您可以在适当的时间在代码隐藏中配置此视图,例如当用户通过您提供的任何输入机制指示他们只想显示喜欢的项目时。

请注意,此方法完全避免尝试使用DataTemplate作为显示或隐藏项目的机制。而是在项目到达ListView对象之前对其进行过滤。

答案 1 :(得分:0)

如果您要查找UWP,只需将MinHeight属性设置为0(零):

<ListView.ItemContainerStyle>
     <Style TargetType="ListViewItem">
          <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
          <Setter Property="MinHeight" Value="0" />

     </Style>
</ListView.ItemContainerStyle>