如何向ItemsControl中的DeviceListItemView传递ViewModel数据?
问题原因与解决方案
核心问题
你的代码存在两个关键问题导致数据无法传递:
DeviceListItemView中的ViewModel是字段而非属性,WPF的数据绑定仅支持作用于属性,无法直接绑定字段。- 你没有将
ItemsControl中每个项的DataContext(即ItemsSource里的DeviceListItemViewModel实例)关联到DeviceListItemView的ViewModel。
解决方案(两种可选)
方案一:利用DataContext传递数据(推荐,更符合WPF常规写法)
这种方式无需额外定义属性,直接通过控件的DataContext传递数据:
- 修改
DeviceListItemView.xaml.cs,移除自行创建的ViewModel字段,依赖继承的DataContext:
public partial class DeviceListItemView : UserControl { public DeviceListItemView() { InitializeComponent(); } // 可选:添加只读属性方便代码中访问ViewModel public DeviceListItemViewModel ViewModel => DataContext as DeviceListItemViewModel; }
- 此时
ItemsControl会自动将每个项的DataContext设置为ItemsSource中对应的DeviceListItemViewModel,DeviceListItemView作为UserControl会继承这个DataContext,你可以直接在DeviceListItemView.xaml中绑定ViewModel的属性(比如{Binding PropertyName})。
方案二:将ViewModel改为依赖属性
如果坚持要通过ViewModel属性传递数据,需要将其改为WPF依赖属性:
- 修改
DeviceListItemView.xaml.cs:
public partial class DeviceListItemView : UserControl { // 定义依赖属性 public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(DeviceListItemViewModel), typeof(DeviceListItemView)); public DeviceListItemViewModel ViewModel { get => (DeviceListItemViewModel)GetValue(ViewModelProperty); set => SetValue(ViewModelProperty, value); } public DeviceListItemView() { InitializeComponent(); } }
- 在
DeviceListView.xaml.cs的SetupBindings方法中添加绑定逻辑:
private void SetupBindings() { var itemViewFactory = new FrameworkElementFactory(typeof(DeviceListItemView)); // 将当前项的DataContext绑定到ViewModel属性 itemViewFactory.SetBinding(DeviceListItemView.ViewModelProperty, new Binding()); DataTemplate dataTemplate = new DataTemplate(); dataTemplate.DataType = typeof(DeviceListItemViewModel); dataTemplate.VisualTree = itemViewFactory; items.ItemsSource = viewModel.items; items.ItemTemplate = dataTemplate; }
额外优化建议
将DeviceListViewModel中的List<DeviceListItemViewModel>改为ObservableCollection<DeviceListItemViewModel>,这样当集合内数据新增、删除时,UI会自动更新:
internal class DeviceListViewModel { public ObservableCollection<DeviceListItemViewModel> items { get; set; } = new ObservableCollection<DeviceListItemViewModel>(); public DeviceListViewModel() { SetupSubscriptions(); } private void SetupSubscriptions() { // updates items property } }
内容的提问来源于stack exchange,提问作者mag_zbc
相关产品推荐
相关产品推荐

