gpt4 book ai didi

c# - 用户选择子项后 TreeView 自动选择父项

转载 作者:行者123 更新时间:2023-12-02 22:33:39 24 4
gpt4 key购买 nike

在我的窗口中有一个 TreeView 和 TextBox。假设 TextBox 用于编写自定义脚本,而 TreeView 是一种选择要插入的函数的方法;想想 Crystal Report 脚本编辑器。

我的目标是让用户单击 TreeView 的其中一个子项,然后将该子项插入到 TextBox 中。 child 是一个函数签名,位于 Parent 节点下。然后用户可以导航到 TextBox,选择一个函数参数并将其替换为另一个函数签名。为此,我处理了 TreeView 的 SelectedItemChanged 事件,设置了 TextBox 的 SelectedText,然后在更改后尝试突出显示文本。

TextBox 的 SelectedText 被正确交换。但是,文本没有突出显示,滚动条也没有滚动到所选文本。

这是我为重现该行为而编写的测试项目中的 XAML:

  <Window x:Class="SelectedTextWeirdness.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:SelectedTextWeirdness="clr-namespace:SelectedTextWeirdness" Title="MainWindow" Width="600" Height="600"
x:Name="Me">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TreeView Grid.Row="0" x:Name="treeView" ItemsSource="{Binding ElementName=Me, Path=TreeViewItems, Mode=TwoWay}"
SelectedItemChanged="treeView_SelectedItemChanged" Margin="10">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type SelectedTextWeirdness:Parent}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type SelectedTextWeirdness:Child}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
<TextBox Grid.Row="1" x:Name="scriptTextBox" Margin="10" Height="200" Width="Auto" FontFamily="Consolas, Courier New"
HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto"
MaxLines="9999" AcceptsReturn="True" AcceptsTab="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Text="{Binding Path=Script, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
/>
</Grid>
</Window>

这是代码隐藏:

  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<Child> Children
{
get;
set;
}
}

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public List<Parent> TreeViewItems
{
get;
set;
}

public MainWindow()
{
BuildTreeViewItems();

InitializeComponent();
}

private void BuildTreeViewItems()
{
TreeViewItems = new List<Parent>()
{
new Parent()
{
Name = "Parent1",
Children =
new List<Child>()
{
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<Child>()
{
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<object> 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 中调用它来推迟焦点。

类似于:

delegate void voidDelegate();

private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
var tree = (TreeView)sender;
var selectedItem = tree.SelectedItem as Child;
if (selectedItem != null)
{
int selectionStart = scriptTextBox.SelectionStart;
string selectedText = selectedItem.Name;
voidDelegate giveFocusDelegate = new voidDelegate(giveFocus);
Dispatcher.BeginInvoke(giveFocusDelegate, new object[] { });
scriptTextBox.SelectedText = selectedText;
}
}

private void giveFocus()
{
scriptTextBox.Focus();
}

应该让您离目标更近。

编辑:我们怎么知道这会起作用?

作为the documentation for Dispatcher.BeginInvoke说:

The operation is added to the event queue of the Dispatcher at the specified DispatcherPriority.

因此,无论您调用 beginInvoke 的任务的优先级如何,调用发生的最近时间是在当前操作执行结束之后:beginInvoked 操作被“推送”到调度程序队列中的某处,这是有效的在一个线程上。

关于c# - 用户选择子项后 TreeView 自动选择父项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11803233/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com