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

WPF横向ListView自定义数据模板实现及数据绑定问题求助

搞定你的WPF+Caliburn.Micro+MaterialDesign双问题!

嘿,作为WPF新手能搭出这样的UI已经很棒了!咱们来逐个解决你遇到的两个问题:数据绑定失效和列表横向布局~


一、先解决数据无法填充到模板的问题

你的代码里有3个关键小问题导致绑定失效,我帮你一一修正:

1. Person模型的FullName逻辑错误+缺少属性变更通知

现在你的FullName setter完全写反了——应该是当FirstName/LastName变化时自动更新FullName,而不是反过来。而且Person类没实现INotifyPropertyChanged,UI根本接收不到属性变化的通知。修改后的Person类应该是这样:

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

public class Person : INotifyPropertyChanged
{
    private string _firstName;
    private string _lastName;

    public string FirstName
    {
        get => _firstName;
        set
        {
            _firstName = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(FullName)); // 改FirstName时,通知FullName更新
        }
    }

    public string LastName
    {
        get => _lastName;
        set
        {
            _lastName = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(FullName)); // 改LastName时,通知FullName更新
        }
    }

    // 用计算属性直接生成FullName,不需要手动set
    public string FullName => $"{FirstName} {LastName}";

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. ViewModel的MyContacts缺少变更通知

你的HomeViewModel里MyContacts的setter没调用NotifyOfPropertyChange,虽然初始化加数据没问题,但后续如果更新列表,UI不会刷新,补上这句:

public List<Person> MyContacts
{
    get => _myContacts;
    set
    {
        _myContacts = value;
        NotifyOfPropertyChange(() => MyContacts); // 补上属性变更通知
    }
}

3. XAML里Caliburn.Micro的绑定语法错了

Caliburn.Micro是基于当前数据上下文做名字绑定的——每个ListViewItem的上下文就是单个Person对象,所以你不需要写Person_FullName,直接写FullName就能绑定到Person的对应属性。同理,FirstName和LastName也直接写属性名:

修改XAML里的文本控件:

<!-- 正面显示全名 -->
<TextBlock x:Name="FullName"/>

<!-- 背面的名字输入框 -->
<TextBox materialDesign:HintAssist.Hint="First name" materialDesign:HintAssist.IsFloating="True" Margin="0 12 0 0" x:Name="FirstName"/>
<TextBox Grid.Row="1" materialDesign:HintAssist.Hint="Last name" materialDesign:HintAssist.IsFloating="True" Margin="0 12 0 0" x:Name="LastName"/>

二、实现横向展示联系人列表

默认ListView是垂直布局的,要改成横向排列,只需要替换它的ItemsPanel,把默认的垂直StackPanel换成横向的WrapPanel(支持自动换行,适配不同窗口宽度):

在你的ListView里添加这段ItemsPanel模板:

<ListView Grid.Column="0" Grid.Row="2" x:Name="MyContacts">
    <!-- 新增:设置横向布局的ItemsPanel -->
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="8"/>
            <!-- 如果你不需要自动换行,也可以用 <StackPanel Orientation="Horizontal"/> -->
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>

    <!-- 你的ItemTemplate部分保持不变(除了绑定修正) -->
    <ListView.ItemTemplate>
        <!-- ... 原有的Flipper卡片代码 ... -->
    </ListView.ItemTemplate>
</ListView>

额外小建议

  • 可以给Flipper外层的Grid加个Margin="8",让卡片之间有间距,布局更美观;
  • Caliburn.Micro的约定绑定真的很省心,记住控件Name和属性名一致就能自动绑定,不用写一堆Binding语法~

修正后你的联系人列表应该会横向排列,每个卡片都能正确显示姓名啦!

内容的提问来源于stack exchange,提问作者Infii

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:19:23