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
相关产品推荐
相关产品推荐

