1

我正在寻找的行为是在 ListView 中选择 Item 会导致聚焦第一个可聚焦的 visualchild。

问题:ItemsControler 中的数据模板化数据没有获得初始焦点。在下面的示例中,有 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# 中的可视化树的情况下获得我想要的东西?应该可以做到这一点,不是吗?

4

2 回答 2

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>
于 2012-08-10T00:36:41.067 回答
1

在 C# 中使用绑定语法将不起作用,因为这是在 XAML 中描述绑定的方式。它可能会创建 的新实例System.Windows.Data.Binding,并将其属性设置为您在 XAML 中设置的等价物,但我不确定ElementName您可以绑定什么以使其正常工作。

我能想到的唯一其他选择是为SelectionChanged事件添加一个处理程序,并手动设置焦点,但这听起来不像您想要的解决方案。

经过进一步检查,我认为绑定解决方案是不可能的。FocusManager.FocusedElement是一个IInputElement,它没有任何与绑定相关的成员。我认为您需要遍历视觉树才能找到第一个可聚焦的对象。像这样的东西应该工作:

// 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;
}
于 2009-02-24T18:02:23.340 回答