【问题标题】:How to select a TabItem based off of it's Header如何根据它的 Header 选择 TabItem
【发布时间】:2013-08-21 15:32:24
【问题描述】:

In my program I have a tabItem that gets selected when a TreeViewItem with an equivalent header is selected.

这是我目前拥有的(有效):

(parent_TreeViewItem.Items.Contains(SelectedItem))
{
          tabControl1.SelectedItem = tabControl1.Items //Changes tab according to TreeView
                .OfType<TabItem>().SingleOrDefault(n => n.Header.ToString() == SelectedItem.Header.ToString());
}

与我这次所做的不同之处在于,我选择的tabItemheader 是由stringinteger 组成的。

例如:选定的TreeViewItem 将始终有一个名为"Arrival"header,但tabItemheader 将具有类似"Arrival" + integer 的形式。 integer 值将来自父节点的header

对于这个过程,我认为我首先需要获取父节点的 header 值,因为它包含我需要的 integer 值。然后我需要以某种方式修改上面的代码以查询具有header 的节点,例如"Arrival" + parentHeader

我该如何做这样的事情?

谢谢。

更新

我当前的代码,使用@varocarbas 的答案。我正在使用涉及将integer curNumber 设置为父级header 的值的答案的第一个版本。单击“到达”节点时,代码编译但不执行任何操作。

if (parent_TreeViewItem.Items.Contains(SelectedItem.Parent)) //Location - Actions tabs
{
       TreeViewItem parentItem = (TreeViewItem)SelectedItem.Parent;
       int curNumber = getNumber(parentItem.Header.ToString());

       tabControl1.SelectedItem = tabControl1.Items //Changes tab according to TreeView
             .OfType<TabItem>().SingleOrDefault(n => n.Header.ToString() == SelectedItem.Header.ToString() + curNumber.ToString());
}

public static int getNumber(string parentNodeHeader)
{
    int curNumber = 0;
    curNumber = Convert.ToInt32(parentNodeHeader);

    return curNumber;
}

更新 2: 因为“到达”节点是我用作父节点的节点的孙子节点,所以我已将第一行中的 if 语句更改为:

 if (parent_TreeViewItem.Items.Contains(SelectedItem.Parent))

【问题讨论】:

  • 所以不要使用n.Header.ToString() = ...,为什么不使用String.StartsWith()。类似n.Header.ToString().StartsWith(SelectedItem.Header.ToString())
  • 有不同的“到达”+数字吗?也就是说,您需要知道确切的数字还是“到达”是唯一重要的部分?
  • 会有不止一个数字。就像有多个位置的到达标签一样。

标签: c# wpf treeview tabcontrol


【解决方案1】:

首先,你必须得到父节点及其头部包含的数字:

TreeViewItem parentItem = (TreeViewItem)selectedItem.Parent;
int curNumber = getNumber(parentItem.Header.ToString());

getNumber 是一个从父节点标头中的确切位置检索数字的函数。为了编写适当的函数,您必须详细说明这一点;暂时,只是基础知识(它提取输入字符串中的所有数字):

private int getNumber(string parentNodeHeader)
{
    int curNumber = 0;

    //Required string-analysis actions
    //Sample functionality: extract all the numbers in the given string
    string outString = "";
    int count = -1;
    do
    {
        count = count + 1;
        Char curChar = Convert.ToChar(parentNodeHeader.Substring(count, 1));
        if (Char.IsNumber(curChar))
        {
            outString = outString + parentNodeHeader.Substring(count, 1);
        }
    } while (count < parentNodeHeader.Length - 1);

    if (outString != "")
    {
        curNumber = Convert.ToInt32(outString);
    }

    return curNumber;
}

然后您必须更新查询以考虑新信息:

 .OfType<TabItem>().SingleOrDefault(n => n.Header.ToString() == selectedItem.Header.ToString() + curNumber.ToString());

更新

上面的函数只是展示了我通常依赖的那种代码;但是对于简单的情况(例如建议将所有数字放在一个字符串中),您可能更喜欢依赖Regex,正如 Viv 所建议的那样。您可能会依赖以下内容:

private int getNumber(string parentNodeHeader)
{
    System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(parentNodeHeader, @"\d+");
    return Convert.ToInt32(m.Value);
}

这个函数只传递它找到的第一组连续数字;结果与上述函数不同,但足以作为概念证明(此答案的意图)。

【讨论】:

  • 为什么你宁愿写一个函数来提取一个数字,而不是仅仅使用一个Regex 并将数字捕获出来?
  • @Viv 我更喜欢函数/循环,因为 IMO 更加清晰、可扩展和适应性强。对于简单的情况,Regex 显然效率更高;但我不确定这种情况下的确切要求;我也很习惯于处理复杂的情况,因此我倾向于默认编写循环/函数(更大的代码,但系统性的编写花费了我很短的时间):)
  • @Viv 我已经用一些正则表达式更新了我的答案。尽管它显示了我在上一条评论中提到的那种限制:一个非常简单的正则表达式是可以接受的,但仅适用于非常特定的条件。我写的是连续数字;如果您想在任何位置考虑任何数字,例如在我的循环中;你必须让它更复杂。另一方面,我的循环可以很容易地传递任何数量或只是连续的:一旦结构到位,扩展/改进它就相对简单。
  • @varocarbas 请看看我的问题。我已经实现了您答案的第一个版本,但它没有影响任何更改,这让我感到困惑,因为看起来一切都是正确的。我应该废弃它并使用新的getNumber 功能吗?
  • @Ericafterdark upate 中的函数返回它找到的第一组连续数字。例如:在 ab1cd32 中,返回 1 或在 123bdc5 123 中。如果这是您想要的,请继续。带有循环的函数返回它找到的所有数字;在最后一个示例中:132 和 1235。我不确定您在使用这些功能中的哪一个(如果有的话)。无论如何,我建议您进行调试以确保一切都按预期工作。
猜你喜欢
  • 2018-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-14
  • 2019-11-11
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
相关资源
最近更新 更多