最终项目中,我已经把SingleCriteriaHighlightTemplateSelector写成了通用类,支持复杂的模板选择。这里先给出SingleCriteriaHighlightTemplateSelector的代码,作为例子展示。

SingleCriteriaHighlightTemplateSelector.cs代码

using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaUI.Demos.Book._19.StoreDatabase
{
    public class SingleCriteriaHighlightTemplateSelector : IDataTemplate
    {
        public IDataTemplate? DefaultTemplate { get; set; }
        public IDataTemplate? HighlightTemplate { get; set; }

        public string? PropertyName { get; set; }
        public string? PropertyValueToHighlight { get; set; }

        public bool Match(object? data) => data is Product;

        public Control? Build(object? param)
        {
            if (param is not Product product)
            {
                return new TextBlock { Text = param?.ToString() ?? string.Empty };
            }

            if (DefaultTemplate is null || HighlightTemplate is null
                || string.IsNullOrEmpty(PropertyName)
                || PropertyValueToHighlight is null)
            {

                return (DefaultTemplate ?? HighlightTemplate)!.Build(product);
            }

            var type = product.GetType();
            var prop = type.GetProperty(PropertyName,
                                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);

            var valueString = prop?.GetValue(product, null)?.ToString();

            var chosen = string.Equals(valueString,
                                       PropertyValueToHighlight,
                                       StringComparison.OrdinalIgnoreCase)
                         ? HighlightTemplate
                         : DefaultTemplate;

            return chosen.Build(product);
        }
    }
}

VariedTemplates.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"
        Height="420" Width="675"
        xmlns:local="using:AvaloniaUI.Demos.Book._19.StoreDatabase"
        x:Class="AvaloniaUI.VariedTemplates"
        Title="VariedTemplates">
    
    <Window.Resources>
        <!-- 默认模板 -->
        <DataTemplate x:Key="DefaultTemplate" x:DataType="local:Product">
            <Grid Margin="0">
                <Border Margin="5"
                        BorderThickness="1"
                        CornerRadius="4">

                    <Grid Margin="3" RowDefinitions="auto,auto">
                        <TextBlock Text="{Binding ModelNumber}" />
                        <TextBlock Grid.Row="1"
                                   Text="{Binding ModelName}" />
                    </Grid>
                </Border>
            </Grid>
        </DataTemplate>

        <!-- 高亮模板 -->
        <DataTemplate x:Key="HighlightTemplate" x:DataType="local:Product">
            <Grid Margin="0">
                <Border Margin="5"
                        BorderThickness="1"
                        BorderBrush="SteelBlue"
                        CornerRadius="4"
                        Background="LightYellow">
                    <Grid Margin="3" RowDefinitions="auto,auto,auto">
                        <TextBlock FontWeight="Bold"
                                   Text="{Binding ModelNumber}" />
                        <TextBlock Grid.Row="1"
                                   FontWeight="Bold"
                                   Text="{Binding ModelName}" />
                        <TextBlock Grid.Row="2"
                                   FontStyle="Italic"
                                   HorizontalAlignment="Right">
                            *** Great for vacations ***
                        </TextBlock>
                    </Grid>
                </Border>
            </Grid>
        </DataTemplate>
    </Window.Resources>


    <ListBox Grid.Row="1"
             Margin="7,3,7,10"
             x:Name="lstProducts"
             HorizontalAlignment="Stretch">
        <ListBox.ItemTemplate>
            <local:SingleCriteriaHighlightTemplateSelector
                DefaultTemplate="{StaticResource DefaultTemplate}"
                HighlightTemplate="{StaticResource HighlightTemplate}"
                PropertyName="CategoryName"
                PropertyValueToHighlight="Travel">        
            </local:SingleCriteriaHighlightTemplateSelector>
        </ListBox.ItemTemplate>
        
        <ListBox.Styles>
            <Style Selector="ListBoxItem">
                <Setter Property="Padding" Value="0" />
            </Style>

            <!-- 默认状态的 Border 外观 -->
            <Style Selector="ListBoxItem Border">
                <Setter Property="Background" Value="White" />
                <Setter Property="BorderBrush" Value="SteelBlue" />
            </Style>

            <!-- 选中时的 Border 外观 -->
            <Style Selector="ListBoxItem:selected Border">
                <Setter Property="Background" Value="DarkRed" />
                <Setter Property="BorderBrush" Value="DarkBlue" />
            </Style>
        </ListBox.Styles>
    </ListBox>
</Window>

VariedTemplates.axaml.cs代码

using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using AvaloniaUI.Demos.Book._19.StoreDatabase;

namespace AvaloniaUI;

public partial class VariedTemplates : Window
{
    private StoreDb1 db = new StoreDb1();
    public VariedTemplates()
    {
        InitializeComponent();
        lstProducts.ItemsSource = db.GetProducts();
    }
}

运行效果

image

 

posted on 2026-02-09 11:34  dalgleish  阅读(6)  评论(0)    收藏  举报