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;
}
}
}