【问题标题】:How to use TreeView.Tag = object?如何使用 TreeView.Tag = 对象?
【发布时间】:2012-07-31 20:48:03
【问题描述】:

类似这样的:

Dictionary<int, string> myData = new Dictionary<int, string>();
myData.Add(1, "England");
myData.Add(2, "Canada");
myData.Add(3, "Australia");
myTreeView.Node[0].Tag = myData;

那我想得到这个对象,我该怎么做呢? 喜欢:

string str = new string();
str = myTreeView.Node[0].Tag[2]; // "str" should be equal to "Canada"
myTreeView.Node[0].Tag[1] = "Spain";
str = myTreeView.Node[0].Tag[1]; // now "str" is equal to "Spain"

第二个问题 - 什么会返回这个表达式:

Dictionary<int, string> myData = new Dictionary<int, string>();
myData.Add(1, "England");
myData.Add(2, "Canada");
myData.Add(3, "Australia");

string str1 = new string();
str = myData[4]; // there isn't such a key as 4

异常还是空?

【问题讨论】:

    标签: c# .net winforms treeview


    【解决方案1】:

    处理节点标签属性的最严格方法是:

    ((TagType)node_identity.Tag).TagProperty = value;
    

    因此 parent 节点的标签属性可以这样处理:

    ((TagType)node_identity.Parent.Tag).TagProperty = value;
    

    child 节点的标签属性可以这样处理:

    ((TagType)node_identity.Nodes[index_of_child].Tag).TagProperty = value;
    

    并且随着每个Nodes[index_identifier]解析为一个节点,更多远程子节点的标签属性可以这样处理:

    ((TagType)node_identity.Nodes[index_of_child].Nodes[index_of_further_child].Tag).TagProperty = value;
    

    等等

    就标记您的字典的假定对象而言...假设您的目的需要在任何地方都使用相同的整数字符串关联,我会简单地将整数键值存储到您的 Tag 字段中,并从中提取关联的字符串也许是一个全局 List DictionaryStrings 对象。然后你可以只将整数索引值存储到你的标签中;并且只有您的 List.

    的字符串值

    然后您将按如下方式读取您的标签值:

    ((int)node_identity.Tag)
    

    鉴于这些假设,您将改为填充您的基础架构:

    List<string> DictionaryStrings = new List<string>;
    DictionaryStrings.Add("Canada"); // etc.
    

    然后您将读取标签以从存储到标签的索引值中提取您的 DictionaryString,如下所示:

    string DictionaryString = DictionaryStrings[((int)node_identity.Tag)];
    

    您的错误消息是针对您尚未添加(在该执行点)到您的字典中的字典的潜在成员的结果。首先完全填充列表或字典;然后只将有效索引属于到列表/字典。

    【讨论】:

    • 我也同意 Ed S 关于考虑子类化 TreeNode 的建议——尤其是在动态填充 TreeView 的情况下。事实上,我会说 TreeNode 的子类化将使编码变得更加简单,这绝对是编程填充 TreeView 的首选方法。
    • 实际上,我收回了这一点。刚刚尝试子类化 TreeNode 并惊讶于需要多少转换。没有隐式转换。我不确定我是否忽略了一些事情......这使得子类化更像是一场噩梦。但从目前的情况来看,我会坚持使用 Tag 实现,除非其他考虑因素相反。
    【解决方案2】:

    Control.Tag 被输入为object,因此您需要将其转换为Dictionary&lt;int, string&gt; 来访问它:

    Dictionary<int, string> dict = (Dictionary<int, string>)myTreeView.Node[0].Tag;
    string str = dict[2];
    

    同样设置一个值:

    var dict = (Dictionary<int, string>)myTreeView.Node[0].Tag;
    dict[1] = "Spain";
    

    如果您尝试访问不存在的密钥,则会抛出 KeyNotFoundException。您可以使用TryGetValueContainsKey 来检查字典是否包含给定的键:

    if(dict.ContainsKey(key))
    {
        var value = dict[key];
    }
    else
    {
    }
    

    TryGetValue 在一次调用中进行查找并将给定变量设置为值(它存在),因此通常是首选。

    string value;
    if(dict.TryGetValue(key, out value))
    {
        //use value
    }
    else { ... }
    

    【讨论】:

    • 是否有机会检查是否有这样的密钥,例如:如果 dict contains key=4 then {.....} else {....}?
    • @Lee: 为什么要转换成 Dictionary?是否可以使用自定义类?
    • @Amir - Dictionary&lt;int, string&gt; 是问题中使用的类型,但是是的,您可以使用任何类型。
    • @Lee:感谢您的提示,我的代码有误。我找到了。
    【解决方案3】:

    异常还是空?

    好吧,您可以自己尝试一下或read the documentation(它会引发异常)。

    此外,您的代码不会像发布的那样编译。 Tag 是一种将任意数据与对象相关联的方法。结果,它的类型是object,所以你需要在使用它之前强制转换它。

    如果您的代码由于过度使用Tag 属性而变得笨拙,我建议您创建自己的节点类型,该节点类型继承自默认的TreeNode(或其他任何类型)并使用该类型的对象填充您的树视图而是。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-05
      • 2015-05-02
      • 1970-01-01
      • 2023-02-03
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 2014-05-18
      相关资源
      最近更新 更多