我有一个按钮,它位于扩展工具包BusyIndicator控件的DataTemplate中。我有一个绑定到BusyIndicator控件可见性的数据触发器(我尝试过一个样式触发器),以便在BusyIndirector可见时让FocusManager将焦点设置为按钮
这不起作用。我还尝试处理BusyIndicator上的IsVisibleChanged事件,通过遍历可视化树将焦点设置在代码后面的按钮上,但这也不起作用。有没有一些特殊的方法可以将键盘焦点设置在按钮上?
我想我也遇到过同样的问题。这是我使用的代码:
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设置焦点似乎对我有效
这篇SO文章描述了如何在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();
}
以下信息是不正确的,因为错误地认为IsFocused是一个将设置焦点的读/写属性。不适用
这是MVVM真正运行良好的另一个地方。如果你不熟悉MVVM,我强烈建议你研究一下。它解决了很多这样的问题,如果实现得当,它可以让你的代码更容易维护。
如果您使用MVVM方法,只需在DataTemplate后面的ViewModel上托管一个布尔属性(我们称之为IsFocused)。例如,我们有一个Customer类,一个包含Customer实例的CustomerViewModel类,然后是包含CustomerViewModel集合的MainViewModel。ItemsControl的ItemsSource属性绑定到CustomerViewModels集合,DataTemplate按钮的IsFocused属性绑定到CustomerViewModel的IsFocked属性。
我不确定你的工作流程,但你基本上可以这样做:
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。