我认为我的问题相当基本,但我找不到答案:
我有一个 TreeView,我不知道如何监视节点的选择。我在处理程序处为TreeView.SelectedItemChanged和设置了断点TreeViewItem.Expanded。当一个节点被展开时,我确实看到了TreeViewItem.Expanded处理程序在工作,但是当点击一个节点时,这些事件都不会被触发。
我究竟做错了什么?
谢谢。
树视图代码:
<TreeView Name="TestsTree" Height="Auto" MinHeight="50" ItemsSource="{Binding Path=TreeNodes, Mode=TwoWay}" TreeViewItem.Expanded="TestsTreeExpanded" TreeView.SelectedItemChanged="TestsTreeSelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=TreeNodes, Mode=TwoWay}" DataType="{x:Type TestExplorer:FolderTreeNode}">
<TreeViewItem Header="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Run Code Online (Sandbox Code Playgroud)
编辑:
我已经尝试使用TreeViewItem.Selected,但它是相同的-当我在一个节点的名称点击没有反应,但是当我点击在扩展区域,无论是TreeViewItem.Selected和TreeViewItem.Selected被解雇。有什么解释吗?
如何处理从 .NET TreeView 控件派生的 C# 类中此处列出的任何树视图通知?
我试图处理点击通知,例如,像这样:
class ExtendedTreeView : TreeView
{
private const Int32 NM_FIRST = (Int32)(0U - 0U);
private const Int32 NM_CLICK = unchecked((Int32)((UInt32)NM_FIRST - 2U));
protected override void WndProc(ref Message m)
{
if (m.Msg == NM_CLICK)
{
MessageBox.Show("NM_CLICK");
}
base.WndProc(ref m);
}
}
Run Code Online (Sandbox Code Playgroud)
但消息框从未显示。这是我第一次尝试使用 Win32 API 来修改 .NET 控件的行为,所以我不知道出了什么问题。
这是处理这些通知的正确方法吗?
仅供参考:我知道 .NET TreeView 控件有一个单击事件。这只是第一次测试。后来我想启用TVS_EX_MULTISELECT样式。由于 .NET TreeView 控件AfterSelect在TVS_EX_MULTISELECT启用时不会触发任何事件,我想稍后调查TVN_SELCHANGED和TVN_ITEMCHANGED通知的行为。
我如何创建这样的树视图:
<TreeViewItem Header="Customers" ItemsSource="{Binding Customers}">
Run Code Online (Sandbox Code Playgroud)
我想创建这样的子项模板
<TreeViewItem Header="{Binding Header}">
<TreeViewItem Header="Delete"/>
<TreeViewItem Header="Open"/>
</TreeViewItem>
Run Code Online (Sandbox Code Playgroud)
但它并不能很好地工作,因为我最终拥有带有数据模板 treeviewitem 的 treeviewitem,但我想覆盖子元素的 controltemplate,而不是父元素。当然,我想避免我的绑定成为 TreeViewItem,也不想用那些静态对象“打开”、“删除”创建子对象。
我有一个像这样的 JSON 列表:
var arr=[
{
"text":"text1",
"id" :"1",
//no parent id
},
{
"text":"text2",
"id" :"2",
"idParent":"1"
},
{
"text":"text3",
"id" :"3",
"idParent":"2"
},
{
"text":"text4",
"id" :"4",
"idParent":"1"
},
{
"text":"text5",
"id" :"5",
//no parent id
},
];
Run Code Online (Sandbox Code Playgroud)
我需要在层次树中转换该列表,如下所示:
var arr = [
{
"text": "Parent 1",
"id" : "1",
"nodes": [
{
"text": "Child 1",
"id" : "2",
"parentid" : "1",
"nodes": [
{
"text": "Grandchild 1",
"id" : "4",
"parentid" : "2",
},
{
"text": "Grandchild …Run Code Online (Sandbox Code Playgroud) 这是我非常简单的例子。(下...)
What it does: TreeView is populated with three Persons, when TreeItem is selected Textfield will be populated with name of the selected person. 如果用户更改名称并从文本字段中失去焦点(或按 Enter),它将更改人员的名称并“更新”TreeView 项目的显示文本。
我的问题是这一行:
selectedItem.valueProperty().set(new Person(selectedPerson.getName(), selectedPerson.getAge()));
Run Code Online (Sandbox Code Playgroud)
多亏了那条线,我才能刷新 TreeView。没有那个,我只能在例如调整窗口大小(或根项目的折叠和展开)期间刷新树视图。
我认为这个解决方案非常愚蠢,必须有一种方法可以更好地对其进行编码。我不能每次都创建一个新的 Person 实例,这对我来说是不可接受的。
我还尝试为 treeView 触发一个事件,但这种方法会混淆焦点,而且它也是一个愚蠢的解决方案。我还找到了这样的解决方案:
treeView.getRoot().getChildren().set(treeView.getSelectionModel().getSelectedIndex(), new TreeItem<MainAppTF.Person>(updatedPerson));
Run Code Online (Sandbox Code Playgroud)
这也是不好的解决方案。
也许可以使用属性绑定找到解决方案,但绑定是“实时/即时”更改,除非我使用 bind() unbind(),但也许 Binding 中有一些我还不熟悉的东西。(我更喜欢听众)
我的主要目标是“提交”我对焦点更改或关键事件的更改,并在那一刻之后立即更新 TreeView。
PS:我将非常感谢真实的例子。
public class MainAppTF extends Application {
private TreeView<Person> treeView;
private final TreeItem<Person> rootNode = new TreeItem<Person>(new Person("Root", 0));
private TextField textField;
@Override
public void start(Stage stage) {
VBox box …Run Code Online (Sandbox Code Playgroud) 我正在使用 Python3 TTK Treeview 来显示一棵树。但首先,子节点没有缩进,只有树的第一个子级别是可见的。父子节点不显示其子节点。
from tkinter import *
from tkinter.ttk import *
Win = Tk()
entries_tree = Treeview(Win, columns = ("Glyph", "Name"), show="tree")
entries_tree.column("#0", width = 20)
entries_tree.column("#1", width = 20)
entries_tree.pack()
#Test
Un = entries_tree.insert("", "end", values = ["X", "Un"])
Deux = entries_tree.insert("", "end", values = ["X", "Deux"])
Trois = entries_tree.insert(Un, "end", values = ["X", "Un Un"], open = True)
Quatre = entries_tree.insert(Un, "end", values = ["X", "Un Deux"])
Cinq = entries_tree.insert(Un, "end", values = ["X", "Un Trois"]) …Run Code Online (Sandbox Code Playgroud) 现在我有这三个代码:
tree["columns"] = ("one", "two", "three")
tree.column("one", width=150)
tree.column("two", width=150)
tree.column("three", width=150)
tree.heading("one", text="Naar")
tree.heading("two", text="Spoor")
tree.heading("three", text="Vetrektijd")
tree['show'] = 'headings'
Run Code Online (Sandbox Code Playgroud)
但我想要做的是将字体大小更改为三列中的 20,但是我该怎么做呢?因为在互联网上我读了一些关于 Style() 的东西,但这在我的代码中不起作用
我想更改 tkinter.treeview 中选定单元格的前景色或背景色。我怎样才能做到这一点?
此链接显示了更改树视图中所有单元格颜色的命令,但我无法让它对单个单元格起作用。
ttk.Style().configure("Treeview", background="#383838",
foreground="white", fieldbackground="red")
Run Code Online (Sandbox Code Playgroud)
我以前写过一个测试代码。请使用此代码导出您的解决方案/建议。谢谢。
此链接显示了如何使用标签来更改一行数据的颜色,即所选项目的颜色,而不是单元格的颜色。
我在尝试Treeview从另一个小部件的回调中取消选择一个项目时遇到了麻烦。我设法在ESCAPE新闻界实施了一个有效的取消选择:
tree.selection_remove(tree.focus())
Run Code Online (Sandbox Code Playgroud)
在绑定到树视图对象本身的回调中。它仅在树视图具有焦点时才有效(但没关系,这是一种理想的行为)。另一方面,从另一个小部件的回调中尝试相同的方法不起作用。
我尝试使用:
tree.selection_clear()
Run Code Online (Sandbox Code Playgroud)
正如这里推荐的那样,但这也不起作用。
重要提示:从与tree.selection_add(iid)作品相同的调用中选择树视图中的项目。与操作另一个小部件(组合框,并且进行调用的小部件是一个框架)相同。基于此,我不认为问题是由于我的代码中的一些愚蠢的错误(错字或类似的东西)造成的。
我的理论是失去焦点是一个问题,因为这是我看到的唯一区别,当相同的代码ESCAPE在其他地方工作但不在其他地方时,所以我试图用tree.focus_set()和获得焦点tree.focus_force(),但这并没有改变任何东西。
我不太明白selection_clear()应该做什么。由于ttk.Treeview从ttk.Misc有关此的文档中继承了此方法,因此很少使用。我在这里或这里找不到任何关于它的东西。我发现的唯一一件事是简洁:
清除当前的 X 选择。
来自 Python shell 帮助(神秘的X坐标是什么?)
那么如何做到这么简单的事情呢?请帮忙,我不知所措。