WPF中TextBox的Drop事件无法更新ViewModel的PathText属性
问题原因分析
这是因为WPF中TextBox.Text属性的绑定默认UpdateSourceTrigger为LostFocus——只有当TextBox失去焦点时,才会将控件上的值同步到绑定的ViewModel属性中:
- 拖放操作完成后,TextBox通常会保持焦点状态,因此不会触发
LostFocus事件,也就不会把路径同步到ViewModel的PathText属性 - 点击Browse按钮时,按钮获得焦点导致TextBox失去焦点,触发了
LostFocus,从而完成了View到ViewModel的值同步
解决方案
有三种可行的解决方式,按MVVM规范优先级排序:
1. 直接更新ViewModel属性(推荐,符合MVVM)
不要在后台代码中直接设置TextBox的Text,而是通过DataContext获取ViewModel,直接更新其PathText属性。由于CommunityToolkit.Mvvm的[ObservableProperty]自动生成了属性变更通知,View会自动同步显示路径:
private void TxtPath_Drop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] paths = (string[])e.Data.GetData(DataFormats.FileDrop); if (paths.Length > 0 && Directory.Exists(paths[0])) { // 替换成你的ViewModel类型 var viewModel = DataContext as YourViewModel; viewModel.PathText = paths[0]; } } e.Handled = true; }
2. 修改绑定的UpdateSourceTrigger
在XAML中修改TextBox的Text绑定,将UpdateSourceTrigger设置为PropertyChanged,这样TextBox的Text值一变化就立即同步到ViewModel:
<TextBox x:Name="TxtPath" AllowDrop="True" Text="{Binding PathText, UpdateSourceTrigger=PropertyChanged}" Drop="TxtPath_Drop" PreviewDragOver="TxtPath_PreviewDragOver"/>
3. 手动触发绑定源更新
如果一定要在后台代码设置TextBox的Text,可以在设置后手动触发绑定的源更新操作:
private void TxtPath_Drop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] paths = (string[])e.Data.GetData(DataFormats.FileDrop); if (paths.Length > 0 && Directory.Exists(paths[0])) { TxtPath.Text = paths[0]; // 手动触发绑定源更新 TxtPath.GetBindingExpression(TextBox.TextProperty)?.UpdateSource(); } } e.Handled = true; }
内容的提问来源于stack exchange,提问作者Sach
相关产品推荐
相关产品推荐

