用户选择子项后,TreeView自动选择父级
在我的窗口中,我有一个TreeView和TextBox。 假设TextBox用于编写自定义脚本,TreeView是一种选择要插入的函数的方法; 想想Crystal Report脚本编辑器。
我的目标是让用户单击TreeView的一个子项,并将该子项插入到TextBox中。 子项是函数签名,位于父节点下。 然后,用户可以导航到TextBox,选择一个function参数并将其替换为另一个function签名。 为此,我处理TreeView的SelectedItemChanged事件,设置TextBox的SelectedText,然后尝试在更改后突出显示文本。
正确交换TextBox的SelectedText。 但是,文本未突出显示,滚动条未滚动到所选文本。
这是我编写的测试项目中的XAML,用于重现行为:
这是代码隐藏:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace SelectedTextWeirdness { public class Child { public string Name { get; set; } } public class Parent { public string Name { get; set; } public List Children { get; set; } } /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public List TreeViewItems { get; set; } public MainWindow() { BuildTreeViewItems(); InitializeComponent(); } private void BuildTreeViewItems() { TreeViewItems = new List() { new Parent() { Name = "Parent1", Children = new List() { new Child() {Name = "ReallyLongFunctionNameNumber1(ReallyLongLeft1, ReallyLongRight1)"}, new Child() {Name = "ReallyLongFunctionNameNumber2(ReallyLongLeft2, ReallyLongRight2)"}, new Child() {Name = "ReallyLongFunctionNameNumber3(ReallyLongLeft3, ReallyLongRight3)"}, new Child() {Name = "ReallyLongFunctionNameNumber4(ReallyLongLeft4, ReallyLongRight4)"}, new Child() {Name = "ReallyLongFunctionNameNumber5(ReallyLongLeft5, ReallyLongRight5)"} } }, new Parent() { Name = "Parent2", Children = new List() { new Child() {Name = "ReallyLongFunctionNameNumber1(ReallyLongLeft1, ReallyLongRight1)"}, new Child() {Name = "ReallyLongFunctionNameNumber2(ReallyLongLeft2, ReallyLongRight2)"}, new Child() {Name = "ReallyLongFunctionNameNumber3(ReallyLongLeft3, ReallyLongRight3)"}, new Child() {Name = "ReallyLongFunctionNameNumber4(ReallyLongLeft4, ReallyLongRight4)"}, new Child() {Name = "ReallyLongFunctionNameNumber5(ReallyLongLeft5, ReallyLongRight5)"} } } }; } private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e) { var tree = (TreeView)sender; var selectedItem = tree.SelectedItem as Child; if (selectedItem != null) { int selectionStart = scriptTextBox.SelectionStart; string selectedText = selectedItem.Name; scriptTextBox.SelectedText = selectedText; scriptTextBox.Focus(); scriptTextBox.Select(selectionStart, selectedText.Length); } } } }
我尝试过设置SelectedItemChanged e.Handled = true。 那没用。 我已经尝试处理TextBox的LostFocus并设置e.Handled = true,但是没有用。 这似乎只在我使用HierarchicalDateTemplate时发生。 如果我将数据更改为仅一个级别,此设置正常。
有任何想法吗?
核心问题是在事件处理程序中进行Focus()
更改。 通过在BeginInvoke
调用Focus来推迟Focus。
就像是:
delegate void voidDelegate(); private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs
应该让你离目标更近。
编辑:我们怎么知道这会起作用?
正如Dispatcher.BeginInvoke
的文档所说:
该操作将添加到指定DispatcherPriority的Dispatcher的事件队列中。
因此,无论您调用beginInvoke的任务的优先级如何,调用可能发生的最近时间是在当前操作的执行结束之后:beginInvoked操作在调度程序队列的某处“推送”,该操作在单个上运行线。