WPF DataGrid加载UserControl时Loaded事件绑定命令未触发排查
问题根因及解决方案
1. 最核心原因:Selector控件的DataContext未正确绑定
你当前定义的Selector控件默认继承了父容器的DataContext(也就是MapViewModel),但你要绑定的OnLoadedCommand是定义在SelectorViewModel类中的,MapViewModel中只有SelectorViewModel属性,没有直接暴露OnLoadedCommand,导致绑定路径匹配失败,命令无法触发。
解决方案二选一:
- 直接给
Selector控件绑定正确的DataContext:
<local:Selector DataContext="{Binding SelectorViewModel}" Grid.Row="0" Margin="{StaticResource SmallLeftTopMargin}" />
- 不修改DataContext,调整命令绑定路径:
<b:InvokeCommandAction Command="{Binding SelectorViewModel.OnLoadedCommand}" />
2. 次要排查点:Interaction触发器命名空间引用错误
目前WPF官方的交互库已经迁移到Microsoft.Xaml.Behaviors.Wpf,如果你还在使用旧版的System.Windows.Interactivity,或者XAML头部的命名空间声明错误,会导致触发器完全不生效。
请确认你的XAML头部有正确的命名空间声明:
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
如果没有正确引用,可通过NuGet安装Microsoft.Xaml.Behaviors.Wpf包后替换即可。
3. 其他排查点
检查你使用的RelayCommand实现是否正常:如果构造RelayCommand时传入的CanExecute委托返回值为false,命令也会无法触发,大多数第三方MVVM框架的RelayCommand默认未传CanExecute时会返回true,如果是你自己实现的RelayCommand可以排查这部分逻辑。
关于异步方法的疑问
async void或者async Task的OnLoaded方法本身不会导致命令不触发,只要命令绑定正确,异步方法会正常执行。你后续将async void改为async Task的写法是更规范的实现,能够避免异步方法未捕获异常导致程序崩溃的问题,该修改没有问题。
内容的提问来源于stack exchange,提问作者Raya

