You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin ListView过滤扩展需求:基于类型开关控件实现列表过滤

Got it, let's walk through how to add those Type-based Switch filters to your Xamarin.Forms ListView. I've implemented similar functionality before, so here's a practical, step-by-step approach that integrates smoothly with your existing setup:

1. Prep Your Data Model & ViewModel

First, let's make sure your data and view layer are set up to handle the filter state:

a. Add a Filter Tracking Class

Create a simple helper class to track each Type's switch state (it needs to implement INotifyPropertyChanged so the UI updates when toggles change):

public class TypeFilter : INotifyPropertyChanged
{
    private string _typeName;
    public string TypeName
    {
        get => _typeName;
        set { _typeName = value; OnPropertyChanged(); }
    }

    private bool _isEnabled = true; // Default to on
    public bool IsEnabled
    {
        get => _isEnabled;
        set { _isEnabled = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

b. Update Your ViewModel

Add these properties to your existing ViewModel (the one bound to ItemsPage.xaml):

// All raw items from SQLite
public ObservableCollection<Item> AllItems { get; set; } = new ObservableCollection<Item>();

// Filtered items displayed in the ListView
public ObservableCollection<Item> FilteredItems { get; set; } = new ObservableCollection<Item>();

// Track search bar input (keep your existing binding)
private string _searchText;
public string SearchText
{
    get => _searchText;
    set { _searchText = value; OnPropertyChanged(); ApplyFilters(); }
}

// Collection of Type filters with switch states
public ObservableCollection<TypeFilter> TypeFilters { get; set; } = new ObservableCollection<TypeFilter>();

Then, load your unique Types from SQLite and populate the TypeFilters collection (do this in your ViewModel's constructor or initialization method):

// Fetch distinct Types from your Items table (adjust query to match your schema)
var allUniqueTypes = await _sqliteConnection.QueryAsync<string>("SELECT DISTINCT TypeName FROM Items");

// Convert to TypeFilter objects
foreach (var type in allUniqueTypes)
{
    var filter = new TypeFilter { TypeName = type };
    // Subscribe to toggle changes to trigger filtering
    filter.PropertyChanged += (s, e) =>
    {
        if (e.PropertyName == nameof(TypeFilter.IsEnabled))
            ApplyFilters();
    };
    TypeFilters.Add(filter);
}
2. Add Switch Controls to Your UI

Update ItemsPage.xaml to add a horizontal scrollable row of switches below your existing SearchBar. We'll use a CollectionView to dynamically generate switches for each Type:

<StackLayout>
    <!-- Your existing SearchBar -->
    <SearchBar 
        Placeholder="Search items..." 
        Text="{Binding SearchText}" 
        Margin="10"/>

    <!-- Type Filter Switches (horizontal scroll) -->
    <ScrollView Orientation="Horizontal" Margin="10,0">
        <CollectionView ItemsSource="{Binding TypeFilters}" HorizontalOptions="Start">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Orientation="Horizontal" Spacing="8" Margin="0,0,15,0">
                        <Label 
                            Text="{Binding TypeName}" 
                            VerticalOptions="Center" 
                            FontSize="Small"/>
                        <Switch 
                            IsToggled="{Binding IsEnabled}" 
                            VerticalOptions="Center"/>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
            <CollectionView.ItemsLayout>
                <LinearItemsLayout Orientation="Horizontal" ItemSpacing="5"/>
            </CollectionView.ItemsLayout>
        </CollectionView>
    </ScrollView>

    <!-- Your existing ListView (bind to FilteredItems instead of AllItems) -->
    <ListView ItemsSource="{Binding FilteredItems}">
        <!-- Keep your existing ItemTemplate here -->
    </ListView>
</StackLayout>
3. Combine Search & Switch Filter Logic

Add the ApplyFilters method to your ViewModel to combine both the SearchBar text and switch states:

private void ApplyFilters()
{
    // Start with all items
    var filteredItems = AllItems.AsEnumerable();

    // Apply SearchBar filter first
    if (!string.IsNullOrWhiteSpace(SearchText))
    {
        filteredItems = filteredItems.Where(item => 
            item.Name.Contains(SearchText, StringComparison.OrdinalIgnoreCase));
    }

    // Apply Type switch filter
    var enabledTypes = TypeFilters.Where(f => f.IsEnabled).Select(f => f.TypeName).ToList();
    if (enabledTypes.Any()) // Only filter if at least one Type is enabled
    {
        filteredItems = filteredItems.Where(item => 
            item.ItemTypes.Any(t => enabledTypes.Contains(t)));
    }

    // Update the displayed items
    FilteredItems.Clear();
    foreach (var item in filteredItems)
    {
        FilteredItems.Add(item);
    }
}
4. Edge Cases to Tweak
  • All switches off: Currently, this code shows all items. If you want to show nothing instead, change the if (enabledTypes.Any()) check to if (enabledTypes.Count > 0) and add an else clause to clear FilteredItems.
  • Performance: If you have a large dataset, add a small delay to the ApplyFilters method (e.g., await Task.Delay(200);) to avoid excessive filtering during rapid typing or toggling.
  • Initial load: Don't forget to call ApplyFilters() once after loading AllItems to populate the initial filtered list.

内容的提问来源于stack exchange,提问作者MrMatt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:53:14