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

WinUI3中ListView如何直接绑定模型对象而非模型的属性?

问题原因

  1. MessageControl中的Message是普通CLR属性,不是依赖属性,WinUI3对x:Bind的实现比UWP更严格,在DataTemplate中无Path的全对象绑定场景,要求目标属性是支持变更通知的依赖属性,普通CLR属性无法正确接收绑定值,这也是你之前UWP代码能运行、迁移到WinUI3后失效的核心原因。
  2. 代码存在笔误:MessageControl对应的XAML文件中x:Class属性写为MessageClient.Controls.EmailControl,与后台类名MessageControl不一致,会导致控件初始化异常。
  3. MainWindow中的Messages、TestMessage是公共字段而非属性,x:Bind仅支持绑定属性,且你在InitializeComponent执行完成后才给字段赋值,默认OneTime模式的绑定已经触发完成,无法拿到后续赋值的数据源。

解决方案

1. 将MessageControl的Message改为依赖属性

替换MessageControl后台的Message属性定义:

public sealed partial class MessageControl : UserControl
{
    public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(
        nameof(Message),
        typeof(Message),
        typeof(MessageControl),
        new PropertyMetadata(null));

    /// <summary>
    /// 待展示的消息
    /// </summary>
    public Message Message
    {
        get => (Message)GetValue(MessageProperty);
        set => SetValue(MessageProperty, value);
    }

    public MessageControl()
    {
        this.InitializeComponent();
    }
}

同时修改XAML的x:Class为正确的类名:

x:Class="MessageClient.Controls.MessageControl"

2. 修正MainWindow的绑定源定义

将公共字段改为属性,如需在InitializeComponent之后赋值,可实现INotifyPropertyChanged接口:

using System.ComponentModel;
using System.Runtime.CompilerServices;

public sealed partial class MainWindow : Window, INotifyPropertyChanged
{
    private ObservableCollection<Message> _messages;
    public ObservableCollection<Message> Messages
    {
        get => _messages;
        set
        {
            _messages = value;
            OnPropertyChanged();
        }
    }

    private Message _testMessage;
    public Message TestMessage
    {
        get => _testMessage;
        set
        {
            _testMessage = value;
            OnPropertyChanged();
        }
    }

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

    public MainWindow()
    {
        this.InitializeComponent();
        this.PopulateTestMessages();
    }

    private void PopulateTestMessages()
    {
        this.Messages = new ObservableCollection<Message>(TestDataGenerator.GetTestMessages(10));
        this.TestMessage = this.Messages.First();
    }
}

修改ListView的ItemsSource绑定为OneWay模式,确保数据源变更时能刷新:

<ListView x:Name="MessagesListView"
          ItemsSource="{x:Bind Messages, Mode=OneWay}">

修改完成后无Path的全对象绑定即可正常生效。


内容的提问来源于stack exchange,提问作者Michael Kintscher they-them

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:06:07