Привязка WPF, где значение = X - PullRequest
3 голосов
/ 08 июля 2011

Привет. Просто хочу услышать, возможно ли в xaml привязать список, где значение имеет определенное значение.Ex.в следующем примере, возможно ли с 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 ]

7 голосов
/ 08 июля 2011

Используйте 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 голос
/ 08 июля 2011

Использование 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>

0 голосов
/ 08 июля 2011

Я поддерживаю решение Леома Бёрка.

Альтернативным решением (в вашем случае) может быть использование ObjectDataProvider с MethodParameters.

Посмотрите раздел примеров на этой странице:
http://msdn.microsoft.com/en-us/library/system.windows.data.objectdataprovider.methodname.aspx

0 голосов
/ 08 июля 2011

Используйте пользовательский шаблон DataTemplate в вашем ListView и используйте 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}" ... />
0 голосов
/ 08 июля 2011

украдено у здесь :

WPF имеет встроенную поддержку фильтрации элементы в списке. ICollectionView имеет свойство Filter, которое может быть установлено в экземпляр Предиката - это делегат, который принимает один объект аргумент и возвращает бул. каждый элемент в списке передается через этот фильтр, чтобы определить, если это отфильтрован или нет.

Пример использования свойства фильтра можно найти здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...