我有一个位于扩展工具包BusyIndicator控件上的DataTemplate中的按钮。我有一个数据触发器(我尝试过一个样式触发器)绑定到BusyIndicator控件的可见性,以便在BusyIndicator可见时让FocusManager将焦点设置到按钮上。
这不起作用。我还尝试在BusyIndicator上处理IsVisibleChanged事件,通过遍历可视化树将焦点设置在代码隐藏中的按钮上,这也不起作用。是否有一些特殊方法可以将键盘焦点设置在按钮上?
答案 0 :(得分:1)
我想我遇到了同样的问题。这是我使用的代码:
public delegate void SimpleDelegate();
private void grid_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (grid.Visibility == System.Windows.Visibility.Visible)
{
TextBox tb = (TextBox)(sender as Grid).FindName("theTextbox");
tb.SelectAll();
Dispatcher.BeginInvoke(DispatcherPriority.Input, new SimpleDelegate(delegate { tb.Focus(); }));
}
}
此代码还会在显示包含文本框的网格时选择所有文本。
也许有更好的方法,但使用Dispatcher设置焦点似乎对我有用。
答案 1 :(得分:0)
This SO article描述了如何在ItemsControl中选择项目的容器并导航树以选择要更改的项目(在这种情况下将其聚焦)。
从下面修改我的代码:
public void WhateverMethodForShowingBusy ()
{
//Get a reference to your View
FrameworkElement myView = this.View; // I generally have a reference to the view living on the ViewModel set at construction time
// Get a reference to your ItemsControl - in this example by name
ListBox custListBox = myView.ListBoxName;
// Get the currently selected Item which will be a CustomerViewModel
// (not a DataTemplate or ListBoxItem)
CustomerViewModel cvm = custListBox.SelectedItem;
//Generate the ContentPresenter
ContentPresenter cp = custListBox.ItemContainerGenerator.ContainerFromItem(cvm) as ContentPresenter;
//Now get the button and focus it.
Button myButton = cp.FindName("MyButtonName");
myButton.Focus();
}
这是MVVM真正运作良好的另一个地方。如果您不熟悉MVVM,我强烈建议您进行调查。它解决了很多这样的问题,如果实施得当,它可以使你的代码更易于维护。
如果您正在使用MVVM方法,只需在位于DataTemplate后面的ViewModel上托管一个布尔属性(我们称之为IsFocused)。例如,我们有一个Customer类,一个CustomerViewModel类,它包含一个customer实例,然后是MainViewModel,它包含一组CustomerViewModel。 ItemsControl的ItemsSource属性绑定到CustomerViewModels集合,DataTemplate按钮的IsFocused属性绑定到CustomerViewModel上的IsFocused属性。
我不确定您的工作流程,但您基本上可以这样做:
public void WhateverMethodForShowingBusy ()
{
//Get a reference to your View
FrameworkElement myView = this.View; // I generally have a reference to the view living on the ViewModel set at construction time
// Get a reference to your ItemsControl - in this example by name
ListBox custListBox = myView.ListBoxName;
// Get the currently selected Item which will be a CustomerViewModel
// (not a DataTemplate or ListBoxItem)
CustomerViewModel cvm = custListBox.SelectedItem;
//Finally set the property.
cvm.IsFocused = true;
}
与MVVM中的所有内容一样,请确保您正在实现INotifyPropertyChanged。