2009-02-20 109 views
1

我找的行爲是在聚焦第一可獲得焦點visualchild一個ListView結果選擇一個項目。焦點的DataTemplate WPF中

問題:在ItemsControler datatemplated數據不得到一個初始聚焦。 在下面的例子中有4個字符串,然後通過Datatemplate填充到TextBox中。

例子:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Grid> 
     <ListView> 
     <ListView.Resources> 
      <DataTemplate DataType="{x:Type sys:String}" > 
       <TextBox Width="100" Text="{Binding Mode=OneWay}"/> 
      </DataTemplate> 
     </ListView.Resources> 
     <ListView.ItemsSource> 
      <x:Array Type="{x:Type sys:String}"> 
       <sys:String>test</sys:String> 
       <sys:String>test</sys:String> 
       <sys:String>test</sys:String> 
       <sys:String>test</sys:String> 
      </x:Array> 
     </ListView.ItemsSource> 
     </ListView> 
    </Grid> 
</Window> 

我已經嘗試過的

FocusManager.FocusedElement="{Binding ElementName=[...]}" 

毫無意義的一些組合的說:沒有成功。 任何人都可以得到我想要的,而不需要遍歷c#中的可視化樹? 應該可以做到這一點,不是嗎?

回答

1

使用C#中的綁定語法是行不通的,因爲那是綁定如何在XAML描述。它可能會創建一個System.Windows.Data.Binding的新實例,並將其屬性設置爲與您在XAML中設置的值相同,但我不確定您將能夠綁定哪些ElementName以正確工作。

我能想到的唯一的其他選擇是爲SelectionChanged事件添加處理程序,並手動設置焦點,但這聽起來不像您想要的解決方案。

經進一步檢查,我不認爲一個綁定的解決方案是可能的。 FocusManager.FocusedElementIInputElement,它沒有任何與綁定相關的成員。我認爲你需要遍歷可視化樹才能找到可聚焦的第一個對象。像這樣的東西應該工作:

// Event handler for the ListBox.SelectionChanged event 
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    ListBox listBox = sender as ListBox; 
    ItemContainerGenerator = generator.listBox.ItemContainerGenerator; 
    ListBoxItem selectedItem = 
     (ListBoxItem)generator.ContainerFromIndex(listBox.SelectedIndex); 
    IInputElement firstFocusable = FindFirstFocusableElement(selectedItem); 
    firstFocusable.Focus(); 
} 

private IInputElement FindFirstFocusableElement(DependencyObject obj) 
{ 
    IInputElement firstFocusable = null; 

    int count = VisualTreeHelper.GetChildrenCount(obj); 
    for(int i = 0; i < count && null == firstFocusable; i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
     IInputElement inputElement = child as IInputElement; 
     if(null != inputElement && inputElement.Focusable) 
     { 
      firstFocusable = inputElement; 
     } 
     else 
     { 
      firstFocusable = FindFirstFocusableElement(child); 
     } 
    } 

    return firstFocusable; 
} 
+0

以及即使我想這樣做手工在C#中我需要得到參考從DataTemplate中,並用一點點運氣不好文本框將有一個以上的級聯的DataTemplates裏面,所以我需要搜索它... 必須有可能把重點放在第一個輸入。 – 2009-02-25 17:13:57

3

FocusManager的工作甜蜜的。

  <DataTemplate x:Key="MyDataTemplate" DataType="ListBoxItem"> 
      <Grid> 
       <WrapPanel Orientation="Horizontal" FocusManager.FocusedElement="{Binding ElementName=tbText}"> 
        <CheckBox IsChecked="{Binding Path=Completed}" Margin="5" /> 
        <Button Style="{StaticResource ResourceKey=DeleteButtonTemplate}" Margin="5" Click="btnDeleteItem_Click" /> 
        <TextBox Name="tbText" 
          Text="{Binding Path=Text}" 
          Width="200" 
          TextWrapping="Wrap" 
          AcceptsReturn="True" 
          Margin="5" 
          Focusable="True"/> 
        <DatePicker Text="{Binding Path=Date}" Margin="5"/> 
       </WrapPanel> 
      </Grid> 
     </DataTemplate>