C# 按数字顺序将子节点添加到TreeViewItem

C# 按数字顺序将子节点添加到TreeViewItem,c#,wpf,treeviewitem,C#,Wpf,Treeviewitem,我有一个带有TreeView项的程序,其中包含带有数字标题的子节点。当子节点添加到TreeViewItem时,我希望以数字方式添加它们,但我不知道如何在其他节点之间添加节点 我猜我会调用一个函数,该函数将对子节点进行排序,将标题转换为整数,将标题与输入的值进行比较,然后在节点标题大于输入的值时停止。必须先输入新节点,然后输入标题大于要添加的新节点的节点 这是最好的方法,还是有更好的方法?请演示最简单的方法。仅供参考,我的TreeViewItem位于我的主窗口中,正在从单独的窗口进行操作 这将使您

我有一个带有
TreeView
项的程序,其中包含带有数字
标题的子节点。当子节点添加到
TreeViewItem
时,我希望以数字方式添加它们,但我不知道如何在其他节点之间添加节点

我猜我会调用一个函数,该函数将对子节点进行排序,将标题转换为
整数
,将标题与输入的值进行比较,然后在节点标题大于输入的值时停止。必须先输入新节点,然后输入标题大于要添加的新节点的节点

这是最好的方法,还是有更好的方法?请演示最简单的方法。仅供参考,我的
TreeViewItem
位于我的主窗口中,正在从单独的窗口进行操作

这将使您了解如何将子节点添加到我的
TreeViewItem

//Global boolean    
// bool isDuplicate;

//OKAY - Add TreeViewItems to location & Checks if location value is numerical
private void button2_Click(object sender, RoutedEventArgs e)
{
      //Checks to see if TreeViewItem is a numerical value
      string Str = textBox1.Text.Trim();
      double Num;

      bool isNum = double.TryParse(Str, out Num);

      //If not numerical value, warn user
      if (isNum == false)
          MessageBox.Show("Value must be Numerical");
      else //else, add location
      {
          //close window
          this.Close();

          //Query for Window1
          var mainWindow = Application.Current.Windows
              .Cast<Window1>()
              .FirstOrDefault(window => window is Window1) as Window1;

          //declare TreeViewItem from mainWindow
          TreeViewItem locations = mainWindow.TreeViewItem;

          //Passes to function -- checks for DUPLICATE locations
          CheckForDuplicate(TreeViewItem.Items, textBox1.Text);

          //if Duplicate exists -- warn user
          if (isDuplicate == true)
             MessageBox.Show("Sorry, the number you entered is a duplicate of a current node, please try again.");
          else //else -- create node
          {
               //Creates TreeViewItems for Location
               TreeViewItem newNode = new TreeViewItem();

               //Sets Headers for new locations
               newNode.Header = textBox1.Text;

               //Add TreeView Item to Locations & Blocking Database
               mainWindow.TreeViewItem.Items.Add(newNode);

           }
       }
}

//Checks to see whether the header entered is a DUPLICATE
private void CheckForDuplicate(ItemCollection treeViewItems, string input)
{
      for (int index = 0; index < treeViewItems.Count; index++)
      {
             TreeViewItem item = (TreeViewItem)treeViewItems[index];
             string header = item.Header.ToString();

             if (header == input)
             {
                   isDuplicate = true;
                   break;
             }
             else
                   isDuplicate = false;
      }
}
//全局布尔值
//布尔是双重的;
//好的-将TreeView项添加到位置并检查位置值是否为数字
私有无效按钮2\u单击(对象发送者,路由目标)
{
//检查TreeViewItem是否为数值
string Str=textBox1.Text.Trim();
双数;
bool isNum=double.TryParse(Str,out Num);
//如果不是数值,则警告用户
如果(isNum==false)
MessageBox.Show(“值必须是数字”);
else//else,添加位置
{
//关窗
这个。关闭();
//查询Window1
var mainWindow=Application.Current.Windows
.Cast()
.FirstOrDefault(窗口=>窗口为窗口1)作为窗口1;
//从主窗口声明TreeViewItem
TreeView项目位置=mainWindow.TreeView项目;
//传递到函数--检查重复的位置
选中重复项(TreeViewItem.Items,textBox1.Text);
//如果存在重复--警告用户
如果(isDuplicate==true)
Show(“对不起,您输入的号码与当前节点重复,请重试。”);
else//else——创建节点
{
//为位置创建树视图项
TreeViewItem newNode=新的TreeViewItem();
//设置新位置的标题
newNode.Header=textBox1.Text;
//将TreeView项添加到位置和阻止数据库
mainWindow.TreeViewItem.Items.Add(新节点);
}
}
}
//检查输入的标题是否重复
私有void CheckForDuplicate(ItemCollection树元素,字符串输入)
{
for(int-index=0;index

谢谢。

以下是一个使用
ModelView
Binding
CollectionView

模型视图

public class MainViewModel
{
  private readonly ObservableCollection<TreeItemViewModel> internalChildrens;

  public MainViewModel(string topLevelHeader) {
    this.TopLevelHeader = topLevelHeader;
    this.internalChildrens = new ObservableCollection<TreeItemViewModel>();
    var collView = CollectionViewSource.GetDefaultView(this.internalChildrens);
    collView.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending));
    this.Childrens = collView;
  }

  public string TopLevelHeader { get; set; }

  public IEnumerable Childrens { get; set; }

  public bool AddNewChildren(double num) {
    var numExists = this.internalChildrens.FirstOrDefault(c => c.Header == num) != null;
    if (!numExists) {
      this.internalChildrens.Add(new TreeItemViewModel() {Header = num});
    }
    return numExists;
  }
}

public class TreeItemViewModel
{
  public double Header { get; set; }
}

希望这有助于

当您的结构变得更加复杂时,我看到了潜在的问题。如何处理具有多个子节点的节点?如果此节点的路径已排序,它的兄弟节点是否也会排序?当你移动一个节点时,你是用它来移动它的子节点,还是将它们添加到一个新的父节点?我现在只处理一个父节点。此
TreeViewItem
的子节点将只分配给一个父节点。然后问题是如何处理子节点的子节点。您需要记住,树结构意味着所有东西都是相互连接的。如果您只使用一条路径来简化所有操作,那么最好将数据放入列表中,并从列表中的数据填充树视图。如果要对其进行排序,则在每次排序后清除并重新填充树视图。这听起来有些过分,但在将节点添加到树状视图后,删除和插入节点要简单得多。好吧,把我的节点放入一个列表,然后每次更新列表时,都更新
树状视图中的子节点
?是的,但你必须遍历列表,并将每个节点作为树状视图中最后一个节点的子节点添加。抱歉,没有看到wpf标记。在wpf中可能有更好的方法。我把它放进一个测试程序中,看看它是如何工作的,我得到的唯一错误是说
public IEnumerable Childrens{get;set;}
。编译器说,
使用泛型类型'System.Collections.generic.IEnumerable'需要'1'类型参数
。也许你知道这意味着什么。@Eric你需要System.Collections而不是System.Collections.Generic使用(NET4)好的,它正在工作。不过,我仍然需要在我的程序中实施它。谢谢。你认为这比@tinstaafl的方法更复杂吗?如果我把所有节点都放在一个列表中呢?
<Window x:Class="WpfStackOverflowSpielWiese.Window21"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window21"
        Height="300"
        Width="300"
        x:Name="tvExample">

  <Grid DataContext="{Binding ElementName=tvExample, Path=ViewModel, Mode=OneWay}">

    <StackPanel Orientation="Vertical">
      <TextBox x:Name="tb" />
      <Button Content="Add"
              Click="AddNewItemOnClick" />
      <TreeView>
        <TreeViewItem Header="{Binding TopLevelHeader, Mode=OneWay}"
                      ItemsSource="{Binding Childrens, Mode=OneWay}">
          <TreeViewItem.ItemTemplate>
            <HierarchicalDataTemplate>
              <TextBlock Text="{Binding Header}" />
            </HierarchicalDataTemplate>
          </TreeViewItem.ItemTemplate>
        </TreeViewItem>
      </TreeView>
    </StackPanel>

  </Grid>

</Window>
public partial class Window21 : Window
{
  public static readonly DependencyProperty ViewModelProperty =
    DependencyProperty.Register("ViewModel", typeof(MainViewModel), typeof(Window21), new PropertyMetadata(default(MainViewModel)));

  public MainViewModel ViewModel {
    get { return (MainViewModel)this.GetValue(ViewModelProperty); }
    set { this.SetValue(ViewModelProperty, value); }
  }

  public Window21() {
    this.InitializeComponent();
    this.ViewModel = new MainViewModel("TopLevel");
  }

  private void AddNewItemOnClick(object sender, RoutedEventArgs e) {
    double Num;
    var isNum = double.TryParse(this.tb.Text, out Num);
    //If not numerical value, warn user
    if (isNum == false) {
      MessageBox.Show("Value must be Numerical");
      return;
    }

    var isDuplicate = this.ViewModel.AddNewChildren(Num);
    if (isDuplicate) {
      MessageBox.Show("Sorry, the number you entered is a duplicate of a current node, please try again.");
      return;
    }
  }
}