2011-11-02 24 views
3

我已經搜索了高和低,但我無法弄清楚這一個。我正在構建一個可編輯項目的ListBox。我有一個DataTemplateListBox.ItemTemplate其中包含(其中包括)TextBlockTextBoxTextBlock始終可見,並且TextBox僅在用戶雙擊TextBlock後纔可見。當用戶點擊列表中的另一個項目時,TextBox再次隱藏以顯示TextBlock。所有這些都很好。見我的代碼:在DataTemplate中顯示和對焦TextBox

XAML

<Window.Resources> 
    <local:GoalCollection x:Key="goals"/> 
    <DataTemplate x:Key="GoalItemTemplate" DataType="local:Goal"> 
     <Grid> 
     <TextBlock Text="{Binding Title}" 
        MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" 
        VerticalAlignment="Center"/> 
     <TextBox Name="EntryBox" 
        Text="{Binding Title}" 
        Visibility="Hidden" 
        BorderBrush="{x:Null}" 
        Padding="-2,0,0,0" 
        Panel.ZIndex="1" 
        Margin="-2,0,0,0"/> 
     </Grid> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition /> 
     <ColumnDefinition Width="2*" /> 
    </Grid.ColumnDefinitions> 
    <ListBox Name="GoalsList" 
     ItemsSource="{Binding Source={StaticResource goals}}" 
     HorizontalContentAlignment="Stretch" 
     ItemTemplate="{StaticResource GoalItemTemplate}" 
     SelectionChanged="GoalsList_SelectionChanged" /> 
</Grid> 

C#

public partial class MainWindow : Window 
{ 
    GoalCollection goals; 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private childItem FindVisualChild<childItem>(DependencyObject obj) 
    where childItem : DependencyObject { ... } 

    protected override void OnInitialized(EventArgs e) 
    { 
     base.OnInitialized(e); 
     goals = (GoalCollection)Resources["goals"]; 
    } 

    private void TextBlock_MouseLeftButtonDown(object sender, 
               MouseButtonEventArgs e) 
    { 
     if (e.ClickCount == 2) 
     { 
      TextBlock tblk = sender as TextBlock; 
      if (tblk == null) 
      return; 
      TextBox tbx = ((Grid)tblk.Parent).FindName("EntryBox") as TextBox; 
      if (tbx == null) 
      return; 
      tbx.Visibility = Visibility.Visible; 
      Keyboard.Focus(tbx); 
     } 
    } 

    private void GoalsList_SelectionChanged(object sender, 
              SelectionChangedEventArgs e) 
    { 
     ListBoxItem lbi; 
     ContentPresenter cp; 
     DataTemplate dt; 
     TextBox tbx; 

     foreach (Goal item in e.RemovedItems) 
     { 
      lbi = (ListBoxItem)GoalsList.ItemContainerGenerator. 
             ContainerFromItem(item); 
      cp = FindVisualChild<ContentPresenter>(lbi); 
      dt = cp.ContentTemplate; 
      tbx = (TextBox)dt.FindName("EntryBox", cp); 
      if (tbx == null) 
      continue; 
      tbx.Visibility = Visibility.Hidden; 
     } 
    } 
} 

說我有是,TextBox立即將焦點轉移回主機ListBoxItem雙擊後的問題。需要額外的(第三次)點擊以專注於TextBox。

通過這個追蹤,我發現TextBox確實獲得焦點。但是它會立即丟失它(嘗試爲TextBox.LostKeyboardFocus事件添加一個處理程序,並逐步從TextBlock_MouseLeftButtonDown()方法中跳過)。有任何想法嗎?

謝謝。

回答

5

我的猜測是點擊事件冒泡到列表框,它通過選擇項目來處理它。

嘗試添加以下內容到Click事件處理程序。如果你想給集中到一個子元素(後Keyboard.Focus(tbx);

e.Handled = true; 
+1

你,先生,是一個天才!我一直在忘記這一點。 – gregsdennis

2

,嘗試的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>