2013-03-04 65 views
0

我在那个主题上搜索了很多,但无法真正找到解决方案,无需使用任何代码。我知道有些人会说使用代码隐藏相关的事情是完全没问题,但我想避免它。WPF在运行时没有代码的情况下设置键盘焦点

我有一个用户控件,它显示一个“对话框”,带有单个文本框和一个确定按钮。该对话框是一个简单的用户控件,放在所有其他对象之上。默认情况下,usercontrols可见性设置为折叠状态。如果usercontrol可见,我想将keyboardfocus设置为对话框usercontrol上的文本框。有什么办法可以在xaml中完全做到这一点吗?由于当控件加载,简单的设置

FocusManager.FocusedElement="{Binding ElementName=tbID}"

将无法​​工作,我的对话框的控制是不是在当时可见。我试图使用某种可见性触发器:

<TextBox Grid.Column="3" 
      Grid.Row="5" 
      Name="tbID" 
      VerticalAlignment="Center"> 
     <TextBox.Style> 
      <Style TargetType="{x:Type TextBox}"> 
       <Style.Triggers> 
        <Trigger Property="Visibility" Value="Visible"> 
         <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=tbID}" /> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </TextBox.Style> 
    </TextBox> 

但这也不工作。触发器被触发,但文本框没有获得焦点。我真的很感激这方面的任何建议。提前致谢!

回答

2

我想你想绑定到UserControlVisibility财产不是TextBox

<UserControl x:Class="WpfApplication7.IconButton" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="100" d:DesignWidth="200" Name="_this"> 
    <Grid> 
     <TextBox Name="tbID" Margin="0,12,0,0" VerticalAlignment="Top"> 
      <TextBox.Style> 
       <Style TargetType="{x:Type TextBox}"> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding ElementName=_this, Path=Visibility}" Value="Visible"> 
          <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=tbID}" /> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </TextBox.Style> 
     </TextBox> 
    </Grid> 
</UserControl> 
+0

这是灵魂!我在你的代码中将** _ this **更改为我的用户控件的名称,它的效果非常好!非常感谢你。 – 2013-03-05 10:08:56

1

您可以尝试使用附加的行为来设置焦点。下面是一些示例代码:

public static class Focus 
{ 
    public static readonly DependencyProperty ShouldFocusWhenVisibleProperty = 
     DependencyProperty.RegisterAttached("ShouldFocusWhenVisible", typeof (bool), typeof (Focus), new PropertyMetadata(default(bool), ShouldFocusWhenVisibleChanged)); 

    private static void ShouldFocusWhenVisibleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     var uiElement = sender as UIElement; 
     if (uiElement == null) return; 

     var shouldFocus = GetShouldFocusWhenVisible(uiElement); 
     if (shouldFocus) 
     { 
      UpdateFocus(uiElement); 
      uiElement.IsVisibleChanged += UiElementOnIsVisibleChanged; 
     } 
     else 
      uiElement.IsVisibleChanged -= UiElementOnIsVisibleChanged; 
    } 

    private static void UiElementOnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     var uiElement = sender as UIElement; 
     if (uiElement == null) return; 

     UpdateFocus(uiElement); 
    } 

    private static void UpdateFocus(UIElement uiElement) 
    { 
     if (!uiElement.IsVisible) return; 

     Keyboard.PrimaryDevice.Focus(uiElement); 
    } 

    public static void SetShouldFocusWhenVisible(UIElement uiElement, bool value) 
    { 
     uiElement.SetValue(ShouldFocusWhenVisibleProperty, value); 
    } 

    public static bool GetShouldFocusWhenVisible(UIElement uiElement) 
    { 
     return (bool)uiElement.GetValue(ShouldFocusWhenVisibleProperty); 
    } 
} 

然后,应用以下的代码到文本框在对话框中:<TextBox local:Focus.ShouldFocusWhenVisible="True" />。请注意,local:需要是对上述Focus类名称空间的引用。

+0

感谢你的努力!这也是一个很好的方式来处理我正在寻找的东西。 – 2013-03-05 10:10:31

+0

只为我工作的解决方案! – rubiktubik 2017-12-30 19:57:28

相关问题