当前位置: 首页 > news >正文

WINUI/WPF——自定义ListView

 

需求概述

首先明确我们要做什么:一个包含4个关注点的配置系统,每个关注点包含​​名称、颜色、半径、启用状态​​四个可配置属性。所有配置需持久化到数据库,并能实时反馈到UI显示上。

  • ​​核心功能点​​:

    1. 关注点属性动态配置

    2. 配置数据实时生效

    3. 所有数据持久化存储

    4. 优雅、用户友好的交互界面

 

需求分析

按上述需求,可以通过一个关注点类,将名称、颜色、半径、启用作为它的属性,同时由于名称是可变化的,最好再添加一个别名或ID的属性,以便在数据库中进行存储。

关注点类:名称与颜色的存储,可以使用字符串,半径使用浮点数,是否启用使用bool值。

 

所有关注点可以形成一个可观察对象的集合,以用于UI上的绑定。

 

需求实现

UI代码如下,以下为WINUI xaml代码,WPF亦可做参考(仅需极少改动即可):

<?xml version="1.0" encoding="utf-8" ?>
<Windowx:Class="WINUIDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:converters="using:WINUIDemo.Converters"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="using:WINUIDemo"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:viewmodels="using:WINUIDemo.ViewModel"mc:Ignorable="d"><StackPanel><StackPanel.Resources><Style x:Key="FocusPointItemStyle" TargetType="ListViewItem"><Setter Property="HorizontalContentAlignment" Value="Left" /><!--  内容左对齐  --><Setter Property="Padding" Value="10" /><!--  内边距  --><Setter Property="Margin" Value="0,0,10,0" /><!--  禁止水平拉伸  --><Setter Property="HorizontalAlignment" Value="Left" /><Setter Property="Width" Value="Auto" /><!--  禁用悬停和选中时的背景变化  --><Setter Property="Background" Value="Transparent" /><Setter Property="BorderBrush" Value="Transparent" /><!--  修改 VisualStateManager 行为  --><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="ListViewItem"><Gridx:Name="ContentBorder"Background="{TemplateBinding Background}"BorderBrush="{TemplateBinding BorderBrush}"BorderThickness="{TemplateBinding BorderThickness}"><ContentPresenterx:Name="ContentPresenter"Margin="{TemplateBinding Padding}"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"Content="{TemplateBinding Content}"ContentTemplate="{TemplateBinding ContentTemplate}"ContentTransitions="{TemplateBinding ContentTransitions}" /></Grid></ControlTemplate></Setter.Value></Setter></Style><DataTemplate x:Key="FocusPointTemplate" x:DataType="viewmodels:FocusPoint"><BorderPadding="10"Background="{ThemeResource CardBackgroundFillColorDefault}"BorderBrush="AliceBlue"BorderThickness="1"CornerRadius="8"><StackPanel Orientation="Horizontal" Spacing="10"><!--  名称  --><TextBoxWidth="100"VerticalAlignment="Center"Text="{x:Bind Name}"TextAlignment="Center" ></TextBox><!--  颜色选择按钮(默认显示图标)  --><Buttonx:Name="ColorPickerButton"Width="32"Height="32"Padding="0"><Button.Content><!--  小图标:显示当前颜色的方块  --><RectangleWidth="20"Height="20"Fill="{x:Bind ToBrush(Color), Mode=OneWay}" /></Button.Content><Button.Flyout><Flyout Placement="Bottom" ShowMode="TransientWithDismissOnPointerMoveAway"><!--  展开后的完整ColorPicker  --><ColorPickerWidth="320"Height="320"ColorSpectrumShape="Ring"IsAlphaEnabled="False"IsColorPreviewVisible="False"Color="{x:Bind Color, Mode=TwoWay}" /></Flyout></Button.Flyout></Button><!--  半径和启用控件  --><StackPanel VerticalAlignment="Center" Orientation="Horizontal"><TextBlockMargin="0,0,10,0"VerticalAlignment="Center"Text="半径" /><NumberBoxWidth="50"Header=""Maximum="50"Minimum="1"Value="{x:Bind Radius, Mode=TwoWay}" /></StackPanel><CheckBoxWidth="Auto"MinWidth="0"Content="启用"IsChecked="{x:Bind IsEnabled, Mode=TwoWay}" /></StackPanel></Border></DataTemplate></StackPanel.Resources><ListViewVerticalAlignment="Center"HorizontalContentAlignment="Center"ItemContainerStyle="{StaticResource FocusPointItemStyle}"ItemTemplate="{StaticResource FocusPointTemplate}"ItemsSource="{x:Bind viewModel.FocusPoints}"Loaded="ListView_Loaded"><ListView.ItemsPanel><ItemsPanelTemplate><!--<ItemsStackPanel Orientation="Horizontal" />--><ItemsWrapGridHorizontalAlignment="Left"VerticalAlignment="Center"MaximumRowsOrColumns="2"Orientation="Horizontal" /></ItemsPanelTemplate></ListView.ItemsPanel></ListView></StackPanel>
</Window>

UI设计亮点​​:

  • ​​集成式颜色选择​​:将ColorPicker嵌入到Flyout中,节省空间,交互优雅。

  • ​​数据绑定​​:所有控件属性均与ViewModel中的数据进行绑定,实现双向更新。

 

 

以下为FocusPoint,使用ObservableObject(MVVMToolkit)来实现属性变更通知。

using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI;
using System;
using Windows.UI;namespace WINUIDemo.ViewModel
{// 关注点数据模型public partial class FocusPoint : ObservableObject{private string name;private string color;private double radius;private bool isEnabled;public string Name{get => name;set { SetProperty(ref name, value); }}public string Color{get => color;set { SetProperty(ref color, value); }}public double Radius{get => radius;set { SetProperty(ref radius, value); }}public bool IsEnabled{get => isEnabled;set { SetProperty(ref isEnabled, value); }}public Microsoft.UI.Xaml.Media.SolidColorBrush ToBrush(string color){return new Microsoft.UI.Xaml.Media.SolidColorBrush(FromHex(color));}private static Color FromHex(string hex){hex = hex.TrimStart('#');byte a = 255; // 默认不透明if (hex.Length == 8){a = Convert.ToByte(hex.Substring(0, 2), 16);hex = hex.Substring(2); // 移除 Alpha 部分
            }byte r = Convert.ToByte(hex.Substring(0, 2), 16);byte g = Convert.ToByte(hex.Substring(2, 2), 16);byte b = Convert.ToByte(hex.Substring(4, 2), 16);return ColorHelper.FromArgb(a, r, g, b);}// 默认值构造函数public FocusPoint(string name, string color, double radius, bool isEnabled){Name = name;Color = color;Radius = radius;IsEnabled = isEnabled;}}}

​设计要点​​:颜色采用Hex字符串存储,便于序列化和数据库存储,同时提供方法与XAML的Brush相互转换。 

 

以下为VM

using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI;
using System.Collections.ObjectModel;namespace WINUIDemo.ViewModel
{public partial class MainViewModel : ObservableRecipient{[ObservableProperty]public ObservableCollection<FocusPoint> focusPoints;public MainViewModel(){FocusPoints = new ObservableCollection<FocusPoint>{new ("关注点1", Colors.Red.ToString(), 10.0, true),new ("关注点2", Colors.Blue.ToString(), 15.0, false),new ("关注点3", Colors.Yellow.ToString(), 15.0, false),new ("关注点4", Colors.Green.ToString(), 15.0, false),};}}
}

 

实现效果

CustomerListview

 

http://www.hskmm.com/?act=detail&tid=11140

相关文章:

  • 用 Rust 实现英文数字验证码识别
  • 图解9:IDEA30款好用的插件
  • 图解10:Redis优化18招
  • 图解11:API和SDK区别
  • Fedora42安装VMware+百度网盘
  • Fedora42安装配置idapro9.1
  • 利用个人账户密码复用获取域凭证:无需接入目标网络的攻击手法解析
  • Java 开发核心疑问解析:从 static 修饰到规范实践
  • 实用指南:坤驰科技诚邀您参加——第十三届中国光纤传大会
  • 2025.9.20
  • 图解8:kafka高效原理
  • Spring Boot 2.5.0 集成 Elasticsearch 7.12.0 实现 CRUD 完整指南(Windows 环境) - 教程
  • TypeScript - typeof 搭配 as const 技巧总结
  • 图解6:网站访问流程
  • 图解7:渲染原理和性能优化
  • [Linux/Docker] BusyBox : 开源、轻量级的Unix工具集
  • Part03 数据结构 - 教程
  • 图解3:幂等使用场景
  • 推荐一款数据库安全产品:全知科技知形-数据库风险监测系统的价值解析
  • 变量,常量,作用域
  • wireshark 进行snmp 协议加密报文解密查看
  • linux kernel synchronization 2
  • MySQL高阶查询语句与视图实战指南 - 指南
  • 订单未支付多种方案
  • 架构风格
  • Twincat 中如何将位变量链接到字节
  • 不管不管,就要你的特殊对待(权限)
  • 202003_攻防世界_功夫再高也怕菜刀
  • 工业软件:重塑协同流程、降低制造成本的关键器具
  • 实用指南:【2025最新版】PCL点云处理算法汇总(C++长期更新版)