BindToLinqFilteredCollection.axaml代码

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Width="360" Height="500"
        xmlns:local="using:AvaloniaUI.Demos.Book._19.StoreDatabase"
        x:Class="AvaloniaUI.BindToLinqFilteredCollection"
        Title="BindToLinqFilteredCollection">
    
    <Grid RowDefinitions="*,auto,*">
        <Grid RowDefinitions="*,auto,auto">
            <ListBox Name="lstProducts" Margin="5,0" DisplayMemberBinding="{Binding ModelName}" x:DataType="local:Product"></ListBox>

            <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="5,2,5,5" HorizontalAlignment="Right">
                <TextBlock VerticalAlignment="Center">Minimum Cost:</TextBlock>
                <TextBox Name="txtMinimumCost" Margin="5,0" Width="40" Text="100" TextChanged="txt_TextChanged"></TextBox>
            </StackPanel>

            <StackPanel Grid.Row="2" HorizontalAlignment="Right" Orientation="Horizontal" Margin="5,2,5,10">
                <Button Margin="2,0,0,0"  Padding="2"
                Click="cmdDeleteProduct_Click">Delete Selected</Button>
                <Button Margin="2,0,0,0"
                Click="cmdAddProduct_Click" Padding="2">Add New</Button>
            </StackPanel>        
        </Grid>

        <GridSplitter Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
                      ResizeBehavior="PreviousAndNext" Height="5"/>

        <Border Grid.Row="3" Padding="7" Margin="7" Background="LightSteelBlue">
            <Grid DataContext="{Binding #lstProducts.SelectedItem}" x:DataType="local:Product"
                  ColumnDefinitions="auto,*" RowDefinitions="auto,auto,auto,auto,*">
            
                <TextBlock Margin="7">Model Number:</TextBlock>
                <TextBox Margin="5" Grid.Column="1" Text="{Binding ModelNumber}"></TextBox>
                <TextBlock Margin="7" Grid.Row="1">Model Name:</TextBlock>
                <TextBox Margin="5" Grid.Row="1" Grid.Column="1" Text="{Binding ModelName}"></TextBox>
                <TextBlock Margin="7" Grid.Row="2">Unit Cost:</TextBlock>
                <TextBox Margin="5" Grid.Row="2" Grid.Column="1" Text="{Binding UnitCost}"></TextBox>
                <TextBlock Margin="7,7,7,0" Grid.Row="3">Description:</TextBlock>
                <ScrollViewer Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2">
                    <TextBox Margin="7" TextWrapping="Wrap" Text="{Binding Description}"></TextBox>
                </ScrollViewer>
            </Grid>
        </Border>
    </Grid>
</Window>

BindToLinqFilteredCollection.axaml.cs代码

using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using AvaloniaUI.Demos.Book._19.StoreDatabase;
using System.Collections.ObjectModel;
using System.Linq;

namespace AvaloniaUI;

public partial class BindToLinqFilteredCollection : Window
{
    private readonly StoreDb1 db = new();

    // 保留所有产品(包括 Add 的)
    private ObservableCollection<Product> allProducts = new();

    // 用于 UI 显示的过滤结果
    private ObservableCollection<Product> filteredProducts = new();

    public BindToLinqFilteredCollection()
    {
        InitializeComponent();

        // 初始化加载所有产品
        allProducts = db.GetProducts();

        // 初始过滤
        ApplyFilter();
    }

    private void ApplyFilter()
    {
        filteredProducts.Clear();

        if (!decimal.TryParse(txtMinimumCost.Text, out var min))
            min = 0;

        foreach (var p in allProducts.Where(p => p.UnitCost >= min))
            filteredProducts.Add(p);

        lstProducts.ItemsSource = filteredProducts;
    }

    private void cmdDeleteProduct_Click(object? sender, RoutedEventArgs e)
    {
        if (lstProducts.SelectedItem is Product p)
        {
            allProducts.Remove(p);
            filteredProducts.Remove(p);
        }
    }

    private void cmdAddProduct_Click(object? sender, RoutedEventArgs e)
    {
        var newP = new Product("00000", "?", 0, "?");
        allProducts.Add(newP);

        // 如果通过过滤则显示
        ApplyFilter();
    }

    private void txt_TextChanged(object? sender, TextChangedEventArgs e)
    {
        // 判断是否为数字
        if (!decimal.TryParse(txtMinimumCost.Text, out _))
            txtMinimumCost.Foreground = Brushes.Red;
        else
            txtMinimumCost.Foreground = Brushes.Black;

        // 重新应用过滤
        ApplyFilter();
    }
}

运行效果

image

 

posted on 2025-12-17 12:38  dalgleish  阅读(0)  评论(0)    收藏  举报