WPF绑定:值等于X

3

你好,我想知道在XAML中是否可以绑定到一个列表,其中一个值具有特定的值。

例如,在下面的示例中,是否可能仅使用XAML显示Price = 20的项目?

我之所以问这个问题,是因为我要绑定包含另一个列表的对象列表,我只想显示某些项目,具体取决于它们的值。因此,我试图避免使用C#解决方案。

MainWindow.xaml

   <Window x:Class="Binding_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListView ItemsSource="{Binding}"/>
    </Grid>
</Window>

MainWindow.xaml.cs

public MainWindow()
        {
            DataContext = BuildList();
            InitializeComponent();
        }

        List<Product> BuildList()
        {
            var list = new List<Product>();
            var y = 1;
            for (var i = 0; i < 100; i++)
            {
                list.Add(new Product{Name = string.Format("Item {0}",i), Price = y++ * 10 });
                if (y > 3)
                    y = 1;
            }
            return list;
        }

Product.cs

public class Product
    {
       public string Name { get; set; }
       public int Price { get; set; }

       public override string ToString()
       {
           return string.Format("{0} \t{1}", Name, Price.ToString("C2"));
       }
}
5个回答

8
使用具有适当筛选器的CollectionViewSource。 在这种情况下,xaml应如下所示:
<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <CollectionViewSource Source="{Binding}" x:Key="filtered" Filter="CollectionViewSource_Filter" />
</Window.Resources>
<Grid>
    <ListView ItemsSource="{Binding Source={StaticResource filtered}}"/>
</Grid>

过滤事件将如下所示:

private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            if ((e.Item as Product).Price == 20)
            {
                e.Accepted = true;
            }
            else
            {
                e.Accepted = false;
            }
        }

1
使用ValueConverter 如果您创建一个以过滤值为参数的ValueConverter,那么您可以使其仅返回您想要的条目。
public class FilterConverter : IValueConverter {

  public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
     var list=value as List<Product>();
     if (list==null) return Binding.DoNothing;
     var stringPrice=parameter as string;
     int price;
     if (!int.TryParse(stringPrice,out price)) return Binding.DoNothing;
     return list.Where(i=>i.Price==price).ToList();
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        return Binding.DoNothing;
  }

}

然后为您的转换器创建一个静态资源,并在绑定中引用它

<Window x:Class="Binding_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:c="PUT A REFERENCE TO THE CONVERTER NAMESPACE HERE!!!"
       Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <c:FilterConverter x:Key="filter" />
  </Window.Resources>
  <Grid>
    <ListView ItemsSource="{Binding Converter={StaticResource filter},ConverterParameter=20}"/>
  </Grid>


0

在您的ListView中使用自定义DataTemplate,并使用DataTrigger确定应该显示哪些项目。类似这样:

<Style x:Key="HideUnlessSomeConditionIsTrue" TargetType="{x:Type TextBlock}">
    <Setter Property="Visibility" Value="Collapsed" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding SomeProperty}" Value="SomeValue">
            <Setter Property="Visibility" Value="Visible" />
        </DataTrigger>
    </Style.Trigger>
</Style>

<TextBlock Style="{StaticResource HideUnlessSomeConditionIsTrue}" ... />

这样做不会导致内存浪费吗?比如说,如果它是一个包含图像的大型列表,而我们只想显示其中的几个。那么这种解决方案仍然会将所有图像加载到列表中,但隐藏不需要的图像。虽然对于小规模来说这是一个很好的解决方案,并且只使用Xaml。 - gulbaek
@Gulbaek 我认为WPF不会加载不可见的项。我知道这在大多数控件中都是这样,但最好再次确认一下。您可以通过将Loaded事件添加到图像并查看是否被调用来轻松测试。个人而言,我通常更喜欢使用CollectionViewSource来完成此操作,但由于您要求仅使用XAML解决方案,因此我发布了此内容。 - Rachel

0

这里盗来的:

WPF内置了对列表中项目的过滤支持。ICollectionView具有Filter属性,可以将其设置为Predicate的实例 - 一个接受单个Object参数并返回bool的委托。列表中的每个项目都会通过该过滤器,以确定它是否被过滤掉。

如何使用过滤属性的示例可以在这里找到


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接