Picker获取焦点时能否通知MV?Focused作为Trigger无效求替代方案
Hey Artanis, great questions—let's tackle them one by one to get your Picker-to-VM interaction working smoothly:
1. Can the Picker send a signal to my ViewModel when it gains focus?
Absolutely! You can pull this off in a clean MVVM-compliant way using behaviors or custom attached properties. Here's the most straightforward approach using event behaviors (works for WPF, MAUI, and Xamarin.Forms):
Example with Behaviors (WPF/Maui)
First, ensure you have the behavior library set up (for WPF, use Microsoft.Xaml.Behaviors.Wpf; MAUI has behaviors built-in as Microsoft.Maui.Controls.Behaviors). Then bind the focus event directly to a command in your ViewModel:
<!-- WPF example --> <Picker> <i:Interaction.Triggers> <i:EventTrigger EventName="GotFocus"> <i:InvokeCommandAction Command="{Binding PickerGotFocusCommand}" /> </i:EventTrigger> </i:Interaction.Triggers> </Picker> <!-- MAUI example --> <Picker> <behaviors:EventToCommandBehavior EventName="Focused" Command="{Binding PickerGotFocusCommand}" /> </Picker>
In your ViewModel, define the command to handle the focus signal:
public ICommand PickerGotFocusCommand { get; } public MyViewModel() { PickerGotFocusCommand = new RelayCommand(OnPickerGotFocus); } private void OnPickerGotFocus() { // Your logic here—this runs when the Picker gains focus }
2. Why isn't the "Focused" Trigger working, and what are alternatives?
The Focused trigger might fail for a few reasons: platform-specific event naming differences (e.g., WPF uses GotFocus instead of Focused), or some UI frameworks don't support Focused as a trigger condition out of the box. Here are reliable alternatives:
Alternative 1: Use Behaviors (Same as Question 1)
As shown above, binding the GotFocus/Focused event directly to a ViewModel command via behaviors is the most robust MVVM approach. It bypasses style trigger limitations and ensures the event is captured reliably.
Alternative 2: Custom Attached Property
If you prefer a code-first approach without behavior libraries, create an attached property to listen for focus events and trigger your ViewModel command:
public static class PickerFocusHelpers { public static readonly DependencyProperty FocusedCommandProperty = DependencyProperty.RegisterAttached( "FocusedCommand", typeof(ICommand), typeof(PickerFocusHelpers), new PropertyMetadata(null, OnFocusedCommandChanged)); public static void SetFocusedCommand(DependencyObject element, ICommand value) { element.SetValue(FocusedCommandProperty, value); } public static ICommand GetFocusedCommand(DependencyObject element) { return (ICommand)element.GetValue(FocusedCommandProperty); } private static void OnFocusedCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is Picker picker) { // Unhook old event handler if needed picker.Focused -= Picker_Focused; if (e.NewValue is ICommand command) { // Hook up the new handler picker.Focused += (s, args) => { if (command.CanExecute(args)) command.Execute(args); }; } } } }
Then use it in your XAML:
<Picker local:PickerFocusHelpers.FocusedCommand="{Binding PickerGotFocusCommand}" />
Alternative 3: Code-Behind (Quick Fix)
If you don't mind a small code-behind touch (still MVVM-friendly if kept minimal), forward the focus event directly to your ViewModel:
private void Picker_Focused(object sender, FocusEventArgs e) { if (DataContext is MyViewModel vm) { vm.OnPickerGotFocus(); } }
Wire up the event in your XAML:
<Picker Focused="Picker_Focused" />
内容的提问来源于stack exchange,提问作者Artanis

