问题描述
我有 DataTemplate
包含 TextBox
。我将这个模板设置为一个选择的列表框项。
我无法将焦点设置为模板中的文本框。我试图调用MyTemplate.FindName,但是它以无效操作异常结束:此操作仅适用于应用此模板的元素。
如何访问你知道 TextBox
的名字吗?重点,这变得相对容易。这个想法是把它应用到 ListBoxItem
本身。
你想要的第一件事做的是得到选定的项目:
var item = listBox1.ItemContainerGenerator.ContainerFromItem(listBox1.SelectedItem)as ListBoxItem;
然后你可以把它传递给这个基于名字的控件, ($ item.IsLoaded)
$ pre $ public $ { $ b {
//等待项目加载,所以我们可以找到控制集中
RoutedEventHandler onload = null;
onload =委托
{
item.Loaded - = onload;
FocusItem(item,name);
};
item.Loaded + = onload;
return;
}
尝试
{
var myTemplate = FindResource(MyTemplateKey)作为FrameworkTemplate; //或者你现在得到你的模板
var ctl = myTemplate.FindName(name,item)作为FrameworkElement;
ctl.Focus();
}
catch
{
//如果找不到模板/项目,请重点关注其他内容?
$ b $ p
$ b
我猜这个棘手的问题是确保你等待要加载的项目。我必须添加该代码,因为我从 ItemContainerGenerator.StatusChanged
事件中调用了该函数,有时还是 ListBoxItem
没有在我们进入方法的时候已经完全初始化了。
I have DataTemplate
containing a TextBox
. I'm setting this template to a listbox item on a selection.
I'm unable to set focus to textbox in the template. I tried to call MyTemplate.FindName, but it ends up with an Invalid Operation Exception: This operation is valid only on elements that have this template applied.
How can I access it?
Since you know the name of the TextBox
you want to focus, this becomes relatively easy. The idea is to get hold of the template as it's applied to the ListBoxItem
itself.
First thing you want to do is get the selected item:
var item = listBox1.ItemContainerGenerator.ContainerFromItem(listBox1.SelectedItem) as ListBoxItem;
Then you can pass that into this little helper function which focuses a control based on its name:
public void FocusItem(ListBoxItem item, string name)
{
if (!item.IsLoaded)
{
// wait for the item to load so we can find the control to focus
RoutedEventHandler onload = null;
onload = delegate
{
item.Loaded -= onload;
FocusItem(item, name);
};
item.Loaded += onload;
return;
}
try
{
var myTemplate = FindResource("MyTemplateKey") as FrameworkTemplate; // or however you get your template right now
var ctl = myTemplate.FindName(name, item) as FrameworkElement;
ctl.Focus();
}
catch
{
// focus something else if the template/item wasn't found?
}
}
I guess the tricky bit is making sure you wait for the item to load. I had to add that code because I was calling this from the ItemContainerGenerator.StatusChanged
event and sometimes the ListBoxItem
hadn't been fully initialized by the time we entered the method.
这篇关于专注于DataTemplate中的TextBox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!