WPF MVVM中用户控件的Dependency Property无法传递至容器的问题求助
你的核心问题是UserControl内部的ListBox选中状态未与UserControl的依赖属性联动,导致HomeViewModel无法接收到选中项的变化。以下是具体修复步骤:
1. 清理UserControl后台代码的重复定义
你的VersionList.cs中重复定义了SelectedVersionProperty和OnSelectionChanged方法,这会引发编译错误,先删除重复部分,保留一份即可:
public partial class VersionsList : UserControl { public VersionsList() { InitializeComponent(); } public VersionPcVue SelectedVersion { get { return (VersionPcVue)GetValue(SelectedVersionProperty); } set { SetValue(SelectedVersionProperty, value); } } public static readonly DependencyProperty SelectedVersionProperty = DependencyProperty.Register("SelectedVersion", typeof(VersionPcVue), typeof(VersionsList), new FrameworkPropertyMetadata( defaultValue: null, flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.AffectsMeasure, propertyChangedCallback: OnSelectionChanged)); private static void OnSelectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { // 若无特殊强制逻辑,可移除该方法或按需实现 } }
注意:给元数据的flags添加FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,让该依赖属性默认支持双向绑定。
2. 让ListBox的SelectedItem绑定到UserControl的依赖属性
修改VersionList.xaml中ListBox的SelectedItem绑定,不再绑定ViewModel的SelectedVersion,改为绑定UserControl自身的SelectedVersion:
<ListBox Grid.Row="1" d:ItemsSource="{d:SampleData ItemCount=5}" ItemsSource="{Binding Versions}" SelectedItem="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:VersionsList}}, Path=SelectedVersion}">
这样ListBox选中项变化时,会直接同步到UserControl的SelectedVersion依赖属性。
3. 优化HomeView的绑定(可选)
因已开启BindsTwoWayByDefault,HomeView中的绑定可省略Mode=TwoWay:
<Controls:VersionsList x:Name="test" Grid.Column="0" DataContext="{Binding VersionsListViewModel}" SelectedVersion="{Binding DataContext.SelectedVersion, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, UpdateSourceTrigger=PropertyChanged}" />
4. 移除UserControlViewModel中冗余的SelectedVersion(可选)
若UserControl的ViewModel无需自行维护选中状态,可删除VersionsListViewModel里的SelectedVersion属性——此时ListBox的选中状态已直接与UserControl的依赖属性绑定,无需ViewModel中转。
完成以上修改后,ListBox选中项变化时,UserControl的SelectedVersion会同步更新,进而传递到HomeViewModel的SelectedVersion属性中。
内容的提问来源于stack exchange,提问作者Stéphan F

