问题描述
我似乎无法解决。任何帮助表示赞赏。
编辑:通过结合@BionicCode提供的Filter逻辑,通过this post在XMAL中实现ListView选择并添加简单的bool Converter er来实现可见性,从而实现了解决方案。我还发现,Items Control也可以在这种情况下工作,并允许每个this post进行更好的控制。
编辑:不幸的是,这还不够。两个ListViews将起作用。请注意添加的命名空间xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
。此外,我添加了“返回”按钮,允许用户返回以选择其他类别。
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:vm="clr-namespace:WpfApp1.viewmodels"
Title="MainWindow" Height="300" Width="500" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<vm:Mainviewmodel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDeFinitions>
<ColumnDeFinition Width="100"/>
<ColumnDeFinition/>
<ColumnDeFinition/>
<ColumnDeFinition/>
</Grid.ColumnDeFinitions>
<Grid.RowDeFinitions>
<RowDeFinition Height="15"/>
<RowDeFinition/>
</Grid.RowDeFinitions>
<Grid Grid.Column="0" Grid.Row="1">
<Button x:Name="BackBtn" Content="Back" Command="{Binding BacktoCatView}"/>
</Grid>
<Grid Grid.Column="1" Grid.Row="1" >
<ListView x:Name="CategoryListView" ItemsSource="{Binding CategoryView}" SelectedItem="{Binding SelectedCategory}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Category}"/>
</DataTemplate>
</ListView.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectedCategoryCommand}" CommandParameter="{Binding SelectedItem,ElementName=CategoryListView}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
</Grid>
<Grid Grid.Column="1" Grid.Row="1" Visibility="{Binding IsBrandView,Converter={StaticResource VisibilityConverter}}">
<ListView ItemsSource="{Binding BrandView}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Brand}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid> </Window>
public class Car : NotifyPropertyChanged
{
private string _brand;
public string Brand
{
get => _brand;
set
{
_brand = value;
OnPropertyChanged();
}
}
private string _category;
public string Category
{
get => _category;
set
{
_category = value;
OnPropertyChanged();
}
}
}
ListView
绑定到一个名为“ CategoryView”的ICollectionView
,它基于Mainviewmodel中的一个ObservableCollection
“ CarsCollection”。
编辑:每个Listview
分别绑定到它们的ICollectionView
,ala,“ CategoryView”和“ BrandView”。 SelectedCategory
绑定到“ CategoryView”中的SelectedItem。
Mainviewmodel:
public class Mainviewmodel : NotifyPropertyChanged
{
private ObservableCollection<Car> _carsCollection;
public ObservableCollection<Car> CarsCollection
{
get { return _carsCollection; }
set
{
_carsCollection = value;
OnPropertyChanged();
}
}
private ICollectionView _categoryView;
public ICollectionView CategoryView
{
get { return _categoryView; }
set
{
_categoryView = value;
OnPropertyChanged();
}
}
private ICollectionView _brandView;
public ICollectionView BrandView
{
get { return _brandView; }
set
{
_brandView = value;
OnPropertyChanged();
}
}
private Car _selectedCategory;
public Car SelectedCategory
{
get { return _selectedCategory; }
set
{
_selectedCategory = value;
OnPropertyChanged();
}
}
public ICommand BacktoCatView { get; private set; }
public ICommand SelectedCategoryCommand { get; private set; }
private bool _isBrandView;
public bool IsBrandView
{
get { return _isBrandView; }
set
{
_isBrandView = value;
OnPropertyChanged();
}
}
public Mainviewmodel()
{
CarsCollection = new ObservableCollection<Car>
{
new Car { Brand = "Chevy",Category = "Sedan" },new Car { Brand = "Mazda",Category = "Sports Car" },new Car { Brand = "Toyota",new Car { Brand = "Honda",new Car { Brand = "Volkswagon",new Car { Brand = "Tesla",new Car { Brand = "Dodge",new Car { Brand = "Jeep",Category = "Off Road" },};
BacktoCatView = new RelayCommand(ShowCategoryView);
SelectedCategoryCommand = new RelayCommand(FilterbyBrand);
//Filter by Category on app start
CategoryView = CollectionViewSource.Getdefaultview(CarsCollection);
CategoryView.Filter = item => !IsDuplicate((IEnumerable<Car>)CategoryView.sourceCollection,(Car)item);
//Setup BrandView for filtering
BrandView = (CollectionView)new CollectionViewSource { Source = CarsCollection }.View;
OnPropertyChanged("CategoryView");
OnPropertyChanged("BrandView");
}
static bool IsDuplicate(IEnumerable<Car> collection,Car target)
{
foreach (var item in collection)
{
// NOTE: Check only the items BEFORE the one in question
if (ReferenceEquals(item,target)) break;
// If more than one Category is present,only show one instance of it
if (item.Category == target.Category) return true;
}
return false;
}
private void ShowCategoryView()
{
IsBrandView = false;
}
public void FilterbyBrand()
{
IsBrandView = true;
BrandView.Filter = item => (item as Car).Category.Equals(_selectedCategory.Category,StringComparison.OrdinalIgnoreCase);
OnPropertyChanged("BrandView");
}
}
}
编辑:在名为“ Helpers”的新名称空间中,将IValueConverter添加到“ Converters”类中以处理可见性。我还在Utility命名空间中添加了一个RelayCommand
类,以简化ICommands的使用。
namespace WpfApp1.Helpers
{
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value,Type targettype,object parameter,CultureInfo culture)
{
var boolValue = (bool)value;
if (boolValue)
return Visibility.Visible;
return Visibility.Collapsed;
}
public object ConvertBack(object value,CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
// Filter by Category
CategoryView = CollectionViewSource.Getdefaultview(CarsCollection);
CategoryView.Filter = item => !IsDuplicate((IEnumerable<Car>)CategoryView.sourceCollection,(Car)item);
static bool IsDuplicate(IEnumerable<Car> collection,Car target)
{
foreach (var item in collection)
{
// NOTE: Check only the items BEFORE the one in question
if (ReferenceEquals(item,target)) break;
// If more than one Category is present,only show one instance of it
if (item.Category == target.Category) return true;
}
return false;
}
此filter可以完美工作,并在CategoryListView中产生以下内容:
Sedan
Sports Car
Off Road
挑战:
当用户从ListView中选择“类别”时,我希望接下来对IListCollection
应用第二个过滤器,以过滤ListView,以使用户选择的“ Category”中的每个“ Brand”都被选中显示在ListView中。
编辑:现在,当用户选择类别时,将向他们显示该特定Brand
的{{1}}的列表。过滤对用户无缝进行。最重要的是,这为用户提供了应用程序启动时的可用类别的即时视图,并且不需要用户在组合框中找到所需的类别。
非常感谢@BionicCode提供的过滤逻辑帮助。
品牌过滤器和Category
bool:
IsBrandView
解决方法
我通过结合@BionicCode提供的Filter逻辑解决了这个问题,根据这篇文章在XMAL中实现了ListView选择,并添加了一个简单的bool Converter er以提高可视性。
解决方案已添加到原始帖子中。