我正在寻找的行为是在ListView中选择一个Item会导致聚焦第一个可聚焦的visualchild。
问题: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#中的可视树,我怎么能得到我想要的东西?
应该可以做到这一点,不是吗?
答案 0 :(得分: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>
答案 1 :(得分: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;
}