WPF绑定,其中value = X

本文关键字:value 其中 绑定 WPF | 更新日期: 2023-09-27 18:01:45

嗨,我只是想知道在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"));
       }
}

WPF绑定,其中value = X

使用带有适当过滤器的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;
            }
        }

使用ValueConverter

如果您创建了一个ValueConvert,它将过滤器值作为参数,那么您可以使它只返回您想要的条目。

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>

从这里偷来的:

WPF内置对过滤的支持列表中的项。ICollectionView已经Filter属性,可以设置为谓词- a的实例委托,它接受单个对象参数并返回bool值。每一个传递列表中的项该过滤器来确定它是否为输入或输出

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

在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}" ... />

我支持Leom Burke的方案。

另一种解决方案(在您的情况下)可能是使用带有MethodParameters的ObjectDataProvider。

请看本页的示例部分:
http://msdn.microsoft.com/en-us/library/system.windows.data.objectdataprovider.methodname.aspx

相关文章: