Binding FocusedElement in HierarchicalDataTemplate
I am trying to focus a control within a HierarchicalDataTemplate. Unfortunately, my attempt to bind to a control within the template is failing. Here is my code:
<HierarchicalDataTemplate DataType="{x:Type TreeView_Experiment:BookmarkPage}">
<DockPanel>
<ToggleButton ... edited for brevity ... />
<Controls:EditableTextBlock x:Name="EditBox" Text="{Binding Path=Title}" VerticalAlignment="Center" IsEditable="True" Focusable="True"/>
</DockPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsFocused, RelativeSource={R开发者_JAVA技巧elativeSource AncestorType={x:Type TreeViewItem}}}" Value="true">
<!-- The Value binding fails with the error: Cannot find source for binding with reference 'ElementName=EditBox -->
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=EditBox}"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
The trigger fires when the treeview item gets the focus, but the {Binding ElementName=EditBox} fails with the message "Cannot find source for binding with reference 'ElementName=EditBox,..."
How can I fix this binding? Or is there a better way to set the focus of a control within a HierarchicalDataTemplate?
Thanks in advance for any help.
I was able to get this working by adding this ugly little bit of code behind. Attach this to the treeview's onselection changed:
private void SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
var treeView = sender as TreeView;
var selectedContainer =
typeof (TreeView).GetProperty("SelectedContainer", BindingFlags.NonPublic | BindingFlags.Instance).
GetValue(treeView, null) as TreeViewItem;
// Find the element we want to focus.
var focusControl = selectedContainer.FindVisualChild<TextBox>();
if (focusControl != null)
focusControl.Focus();
}
The following extension method is required:
public static T FindVisualChild<T>(this DependencyObject obj) where T : DependencyObject
{
var childCount = VisualTreeHelper.GetChildrenCount(obj);
for (int i = 0; i < childCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T)
{
return (T)child;
}
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
{
return childOfChild;
}
}
return null;
}
Instead of looking at the TreeView and trying to find the item to focus, it may be better to have the TreeViewItem itself do the focusing.
精彩评论