简体   繁体   English

以编程方式设置焦点以控制项目中的控件数据模板

[英]Programatically set focus to control in itemscontrol datatemplate

I have a headered items control bound to an observable collection. 我有一个绑定到可观察集合的标头项目控件。 The items in the collection are associated with a data template. 集合中的项目与数据模板相关联。 The data template is pretty simple in that it only contains two text boxes. 数据模板非常简单,因为它仅包含两个文本框。 The part I am having difficulty with is setting focus to the text boxes programatically. 我遇到的困难是通过编程将焦点设置到文本框。

When the items control is first displayed it always has one item in it. 第一次显示项目控件时,它始终包含一个项目。 It may or may not have a value that is bound to the first text box. 它可能具有也可能没有绑定到第一个文本框的值。 If it has a value, the focus needs to be set to the second text box. 如果它有一个值,则需要将焦点设置到第二个文本框。 I've done this using the following: 我使用以下方法完成了此操作:

    protected override void OnActivated(EventArgs e)
    {
        base.OnActivated(e);

        if (_activated) return;

        _activated = true;

        var dc = DataContext as MyViewModel;
        if (null != dc)
        {

            var cp = theItemsControl.ItemContainerGenerator.ContainerFromIndex(0) as ContentPresenter;
            var tb = FindVisualChildren<TextBox>(cp);
            if (tb != null)
            {
                if (!String.IsNullOrEmpty(dc.TheCollection.First().FirstValue))
                {
                    var t = tb.FirstOrDefault(box => box.Name == "SecondTextBox");
                    if (null != t) t.Focus();
                }
                else
                {
                    var t = tb.FirstOrDefault(box => box.Name == "FirstTextBox");
                    if (null != t) t.Focus();
                }
            }
        }
    }

This seems to work fine. 这似乎很好。 However, now, when a new item is added to the collection I need to set focus to the FirstTextBox. 但是,现在,当将新项目添加到集合中时,我需要将焦点设置在FirstTextBox上。 I've tried setting focus in the datatemplate using the FocusManager, but that prohibits the above code from working correctly. 我尝试使用FocusManager在数据模板中设置焦点,但是这阻止了上面的代码正常工作。 I've also tried the following in the view. 我也在视图中尝试了以下方法。 The method gets called from the ViewModel after the new item has been added to the ObservableCollection. 在将新项添加到ObservableCollection之后,将从ViewModel调用该方法。 The code runs, but it fails to find any textboxes (ie. tb == null). 该代码可以运行,但是找不到任何文本框(即tb == null)。 Have the controls been created at this point? 此时是否已创建控件?

    public void SetFocusToNewItem(int index)
    {
        var dc = DataContext as MyViewModel;
        if (null != dc)
        {

            var cp = theItemsControl.ItemContainerGenerator.ContainerFromIndex(index) as ContentPresenter;
            var tb = FindVisualChildren<TextBox>(cp);
            if (tb != null)
            {
                  var t = tb.FirstOrDefault(box => box.Name == "FirstTextBox");
                  if (null != t) t.Focus();
            }
        }
    }

Are there other solutions to set focus after the item has been added? 添加该项目后,还有其他解决方案来设置焦点吗?

Sometimes the following trick works for me: 有时,以下技巧对我有用:

// Replace such call:
SetFocusToNewItem(newIndex);

// By this:
Dispatcher.BeginInvoke((Action) (() =>
{
    SetFocusToNewItem(newIndex);
}));

The problem is when you add an item in collection UI elements is not created, so you can't get it. 问题是当您在集合UI元素中添加项目时未创建,因此无法获取它。 This code above delays your function executing and you method should be executed after UI is created. 上面的这段代码延迟了您的函数执行,您的方法应在创建UI后执行。

PS: You can move Dispatcher call inside of your method. PS:您可以将Dispatcher调用移到方法内部。

EDIT : 编辑

This may help too (works for me): 这可能也有帮助(对我有用):

var cp = theItemsControl.ItemContainerGenerator.ContainerFromIndex(index) as ContentPresenter;
cp.Loaded += (s, e2) => 
            {
                var tb = FindVisualChildren<TextBox>(e2.Source as UIElement)
                         .FirstOrDefault();
                if (tb != null)
                    tb.Focus();
            };

The reason is the same: UI element was not created. 原因相同:未创建UI元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM