gpt4 book ai didi

c# - 使用 LinQ 过滤 ObservableCollection

转载 作者:行者123 更新时间:2023-12-03 13:00:26 25 4
gpt4 key购买 nike

我有一个 MVVM 应用程序,我正在尝试通过 LinQ 对从基于 Entity Framework 的数据库获取的 ObservableCollection 进行过滤。

在 View 模型中我有这个:

public class MenuListViewModel : BaseViewModelCollection<Menu>

{
private string filterString;

public string FilterString
{
get { return filterString; }
set
{
if (Equals(value, filterString)) return;
filterString = value;
RaisePropertyChanged();
}
}

//TODO problems with notification, filter doesn't work
public ObservableCollection<Menu> FilteredItems
{
get
{
if (filterString == null) return Items; //Items is Observable Collection that contains every Item
var query = Items.Where(x => x.Time.ToString().StartsWith(filterString));
return new ObservableCollection<Menu>(query);
}
}

public MenuListViewModel(MenuService menuService)
{
base.Service = menuService; //Using IoC to get service
}
}

在 Xaml 中,我有以下绑定(bind):

 <TextBox x:Name="RecipeFilterBox" Margin="5,5,0,0" TextWrapping="Wrap" Text="{Binding FilterString, NotifyOnTargetUpdated=True}" Grid.Column="1" Height="47.07" VerticalAlignment="Top"/>

问题是,当我在文本框中写入任何内容时,没有任何变化。我知道 propertyChanged 事件有问题,但我真的不知道如何解决这个问题。如果您需要有关此应用程序的更多信息,请询问我。

编辑:FilteredItems 的 xaml 如下所示:

    <ListBox x:Name="MenuItemsListView" ItemsSource="{Binding FilteredItems}" SelectedItem="{Binding DeletedItem, Mode=OneWayToSource}" Foreground="#FFFFEDD3" FontFamily="Segoe Print" FontWeight="Bold" FontSize="18.667" Grid.ColumnSpan="3" Grid.Row="1" ItemContainerStyle="{DynamicResource ListBoxItemStyle1}" Style="{DynamicResource ListBoxStyle1}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Recipe.Name}" Width="255"/>
<TextBlock Width="175" Text="{Binding Time, Converter={StaticResource EnumTimeToItsDescriptionValueConverter}, Mode=OneWay}" />
<TextBlock Text="{Binding Date, StringFormat=dd.MM.yyyy}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

最佳答案

您可以使用 ICollectionView 来实现此目的.

使用FilteredItems作为 ICollectionView 的基础来源并暴露ICollectionView到你的 View 而不是 ObservableCollection<Menu>

使用过滤器委托(delegate)提供过滤器逻辑

FilteredItems.Filter = item =>
{
Menu m = item as Menu;
return m.Time.ToString().StartsWith(FilterString);
}

FilterString更改调用 FilterItems.Refresh();

这是一个例子:

public class MenuListViewModel : BaseViewModelCollection<Menu>
{
public MenuListViewModel()
{
var data = new List<Menu> { some data ... }; // your real list of menus
// initialize the collection view
FilteredItems = CollectionViewSource.GetDefaultView(data);
// apply filtering delegate
FilteredItems.Filter = i =>
{
// This will be invoked for every item in the underlying collection
// every time Refresh is invoked
if (string.IsNullOrEmpty(FilterString)) return true;
Menu m = i as Menu;
return m.Time.ToString().StartsWith(FilterString);
};
}

private string filterString;
public string FilterString
{
get { return filterString; }
set
{
if (Equals(value, filterString)) return;
filterString = value;
FilteredItems.Refresh(); // tirggers filtering logic
RaisePropertyChanged("FilterString");
}
}

public ICollectionView FilteredItems { get; set; }
}

您还必须更改 UpdateSourceTrigger在您的过滤器上TextBox使其更新FilterString每次用户更改文本时。

Text="{Binding FilterString, UpdateSourceTrigger=PropertyChanged, ...}

关于c# - 使用 LinQ 过滤 ObservableCollection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30007961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com