问题
I have a program with a TreeView
Item that holds child nodes with numerical headers
. When adding child nodes to the TreeViewItem
I would like to add them numerically, but I don't know how to add nodes in between other ones.
I'm guessing I would call to a function that would sort through the child nodes, convert the headers to integers
, compare the header with the entered value, and then stop when a node header is greater than the value entered. The new node would have to be entered before the node with the header greater than the new node being added.
Is this the best approach, or is there a better one? Please demonstrate the easiest way to go about this. FYI, my TreeViewItem
is in my main window, and being worked on from a separate window.
This should give you an idea of how I add child nodes to my 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;
}
}
Thank you.
回答1:
Here is a little example for your special case using ModelView
, Binding
and CollectionView
ModelViews
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; }
}
Xaml
<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>
Xaml code behind
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;
}
}
}
hope that helps
来源:https://stackoverflow.com/questions/17931706/adding-child-nodes-to-a-treeviewitem-in-numerical-order