UWP中如何通过绑定设置TextBlock的焦点状态
绑定TextBox焦点状态的实现方案
先说明两个关键点:
- 你代码里用的是
TextBox(不是TextBlock),它本身支持获得焦点;如果是TextBlock的话,需要额外设置IsTabStop="True"和AllowFocusOnInteraction="True"才能获得焦点。 - 控件的
IsFocused是只读属性,没法直接双向绑定来控制焦点,得用下面几种方法实现:
方法1:自定义附加属性(最通用)
写一个简单的附加属性,绑定ViewModel里的布尔值,当值为true时自动让控件获取焦点。
附加属性代码
public static class FocusHelper { public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached( "IsFocused", typeof(bool), typeof(FocusHelper), new PropertyMetadata(false, OnIsFocusedChanged)); public static bool GetIsFocused(DependencyObject obj) { return (bool)obj.GetValue(IsFocusedProperty); } public static void SetIsFocused(DependencyObject obj, bool value) { obj.SetValue(IsFocusedProperty, value); } private static void OnIsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if ((bool)e.NewValue) { var control = d as Control; control?.Focus(FocusState.Programmatic); // 可选:绑定触发后重置属性,避免重复触发 SetIsFocused(d, false); } } }
XAML里用起来
给你的TextBox加上这个附加属性,绑定ViewModel里的布尔属性(比如叫IsTextBoxFocused):
<TextBox x:Name="block1" Text="{Binding Text_, Mode=TwoWay}" Style="{ThemeResource TextFieldStyle}" AllowFocusOnInteraction="True" FontSize="14" MinWidth="274" Height="30" RelativePanel.Below="seperator1" Margin="12 12 12 0" local:FocusHelper.IsFocused="{Binding IsTextBoxFocused, Mode=OneWay}"/>
之后在ViewModel里,只要把IsTextBoxFocused设为true,TextBox就会自动获得焦点。
方法2:用行为组件(更简洁)
如果你的项目已经引用了Microsoft.Xaml.Behaviors(WinUI/UWP用Microsoft.Xaml.Behaviors.Uwp.Managed,WPF用Microsoft.Xaml.Behaviors.Wpf),可以直接用现成的FocusBehavior:
XAML代码
<TextBox x:Name="block1" Text="{Binding Text_, Mode=TwoWay}" Style="{ThemeResource TextFieldStyle}" AllowFocusOnInteraction="True" FontSize="14" MinWidth="274" Height="30" RelativePanel.Below="seperator1" Margin="12 12 12 0"> <interactivity:Interaction.Behaviors> <core:FocusBehavior IsFocused="{Binding IsTextBoxFocused}"/> </interactivity:Interaction.Behaviors> </TextBox>
记得在XAML头部加命名空间:
xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:core="using:Microsoft.Xaml.Interactions.Core"
方法3:ViewModel通知View手动设焦点
要是不想用上面的方法,也可以在ViewModel里定义一个事件,View订阅后直接调用控件的Focus方法:
ViewModel代码
// 定义事件 public event Action RequestTextBoxFocus; // 需要触发焦点时调用这个方法 private void TriggerTextBoxFocus() { RequestTextBoxFocus?.Invoke(); }
View的代码-behind
public MainPage() { InitializeComponent(); var vm = DataContext as YourViewModel; vm.RequestTextBoxFocus += () => block1.Focus(FocusState.Programmatic); }
内容的提问来源于stack exchange,提问作者soundappan kishore
相关产品推荐
相关产品推荐

