【问题标题】:Binding Visiblity of ListViewItemListViewItem 的绑定可见性
【发布时间】:2015-05-08 22:45:41
【问题描述】:

我正在为 Windows Phone 8.1 开发应用程序。在那个应用程序中,我想将ObservableCollection<DisruptionDisplayElement> 的项目绑定到ListViewDisruptionDisplayElement 有一个名为 bool IsFavorite 的属性。在 ListView 我想隐藏所有项目,其中IsFavorite 为假。 如果我通过使用ItemContainerStyle 来执行此操作并使用转换器将Visibility-Property 设置为折叠,则它不起作用。如果我以相同的方式定义 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();
        }
    }
}

中断显示元素:

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 而不会浪费所有空间给空的 ListViewItems?

编辑: 高级代码提供

【问题讨论】:

    标签: c# xaml listview winrt-xaml


    【解决方案1】:

    如果没有a good, minimal, complete code example,就不可能提供在您的确切场景中显示正确技术的实际代码示例。

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

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

    举个例子:

    ICollectionView view = CollectionViewSource.GetDefaultView(DisruptionDisplayList);
    
    view.Filter = item => ((MyClass)item).IsFavorite;
    

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

    请注意,这种方法完全避免尝试使用DataTemplate 作为显示或隐藏项目的机制。相反,项目在到达ListView 对象之前就被过滤掉了。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2013-12-13
        • 2014-08-20
        • 2011-12-18
        • 2012-02-09
        • 1970-01-01
        • 2010-09-27
        • 2011-12-14
        • 1970-01-01
        • 2010-11-02
        相关资源
        最近更新 更多