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();
}
}
运行效果

浙公网安备 33010602011771号