2013-05-01 75 views
4

比方说,我有一个项目控件绑定到VM上的项目列表。数据模板内部是一个文本框。我如何将焦点设置到XAML或VM中的第一个文本框?将焦点设置为项目控件中的第1个文本框

在此先感谢您的帮助!在XAML

public static class InitialFocusBehavior 
{ 
    public static bool GetFocus(DependencyObject element) 
    { 
     return (bool)element.GetValue(FocusProperty); 
    } 

    public static void SetFocus(DependencyObject element, bool value) 
    { 
     element.SetValue(FocusProperty, value); 
    } 

    public static readonly DependencyProperty FocusProperty = 
     DependencyProperty.RegisterAttached(
     "Focus", 
     typeof(bool), 
     typeof(InitialFocusBehavior), 
     new UIPropertyMetadata(false, OnElementFocused)); 

    static void OnElementFocused(
     DependencyObject depObj, DependencyPropertyChangedEventArgs e) 
    { 
     FrameworkElement element = depObj as FrameworkElement; 
     if (element == null) 
      return; 
     element.Focus(); 
    } 
} 

然后将其绑定到真正的元素,你要关注:

<ItemsControl ItemsSource="{Binding UsageItems}" Grid.Row="1" Focusable="False"> 
<ItemsControl.ItemTemplate> 
    <DataTemplate> 
      <Grid Margin="0,0,0,3"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="100"/> 
       <ColumnDefinition Width="10"/> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="10"/> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="10"/> 
       <ColumnDefinition Width="Auto"/> 
      </Grid.ColumnDefinitions> 

      <TextBlock Text="{Binding Month}" Style="{StaticResource Local_MonthLabel}" /> 
      <core:NumericTextBox Value="{Binding Actual, Mode=OneWay}" Style="{StaticResource Local_ActualUsageEntry}" Grid.Column="2"/> 

      <core:ValidationControl Instance="{Binding Model}" Grid.Column="4" PropertyName="{Binding MonthNumber, StringFormat=AdjustedUsage{0}}"> 
       <core:NumericTextBox Value="{Binding Adjusted}" DefaultValueIfNull="0" Style="{StaticResource Local_AdjustUsageEntry}" x:Name="AdjustmentEntry" inventoryLocationSetup:InitialFocusBehavior.Focus="True" /> 
      </core:ValidationControl> 

      <telerik:RadComboBox ItemsSource="{Binding Converter={StaticResource Converter_EnumToEnumMemberViewModel}, Mode=OneTime, Source={x:Type Enums:UsageAdjustmentTypes}}" SelectedValue="{Binding Code, Mode=TwoWay}" Grid.Column="6" Style="{StaticResource Local_CodeSelector}"/> 

     </Grid> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 

回答

3

我使用附加的行为

<TextBox Width="200" Height="20" local:InitialFocusBehavior.Focus="True" /> 

=== UPDATE ===

对不起,上面的代码只是展示了如何使用一个行为来给页面上的控件赋予焦点,如果你想要将它做到ItemControl的第一个项目中的元素,那么你必须将行为应用到ItemsControl本身,然后在更新处理器做这样的事情,而不是找孩子:

static void OnElementFocused(DependencyObject depObj, DependencyPropertyChangedEventArgs e) 
{ 
    ItemsControl itemsControl = depObj as ItemsControl; 
    if (itemsControl == null) 
     return; 
    itemsControl.Loaded += (object sender, RoutedEventArgs args) => 
    { 
     // get the content presented for the first listbox element 
     var contentPresenter = (ContentPresenter)itemsControl.ItemContainerGenerator.ContainerFromIndex(0); 

     // get the textbox and give it focus 
     var textbox = contentPresenter.ContentTemplate.FindName("myTextBox", contentPresenter) as TextBox; 
     textbox.Focus(); 
    }; 
} 

你会发现,我设置的焦点装载的处理程序中,因为我假定项目将不会一直当控件第一次创建时附加。

而且你可能已经想通了由“本地”就是这样的InitialFocusBehavior类中定义的命名空间,你需要在XAML的顶部添加这样的事情:

xmlns:local="clr-namespace:YourProjectNamespace" 
+0

感谢马克,我试图测试一下,但它不喜欢XAML,全是红色。 “本地:”来自哪里?对不起,不是XAML开发人员。 :-) – user2041189 2013-05-02 13:34:59

+0

好吧,我试过了,它不起作用。 ItemsControl DataTemplate中的焦点甚至不在控件中,而是位于控件之外的文本框中。它确实弹出到OnElementFocused中,但是它为每个创建的控件提供了一次该方法(对于它所绑定的项目列表中的每个项目都是1),这导致我相信即使这样做能够设置将焦点放在最后一个文本框中,而不是第一个。任何其他想法?我将在下面发布我的xaml。 – user2041189 2013-05-02 14:04:56

+0

在原始问题中发布xaml,谢谢。 – user2041189 2013-05-02 14:07:18

相关问题