2013-07-31 4 views
1

Этот вопрос является вопросом до this вопроса. Я принял некоторые советы с этого сайта и решил начать обучение MVVM для моей работы с TreeViews. С учетом сказанного я ОЧЕНЬ новичок в MVVM, и я все еще знаком с синтаксисом и реализацией.Как добавить TreeViewItems в элемент управления TreeView

У меня есть TreeView, который отображает данные целочисленного типа, но я бы хотел, чтобы он работал со строками. Дерево также позволяет пользователю добавлять на любой уровень, выбирая TreeViewItem, а затем вводит новый цельный заголовок в текстовое поле, а затем нажимает кнопку.

Example Image

Я хотел бы для одного из родителей, детей и внуков будут доступны при запуске с предопределенными именами. Еще одна вещь, которую следует отметить, заключается в том, что этот пользователь сможет добавлять к TreeView только на уровне дочернего элемента (чтобы они могли добавлять внуков).

Модель

public class TreeViewModel : PropertyChangedBase 
{ 
    public string Value { get; set; } 

    public ObservableCollection<TreeViewModel> Items { get; set; } 

    public CollectionView ItemsView { get; set; } 

    public TreeViewModel(string value) 
    { 
     Items = new ObservableCollection<TreeViewModel>(); 
     ItemsView = new ListCollectionView(Items) 
     { 
      SortDescriptions = 
      { 
       new SortDescription("Value",ListSortDirection.Ascending) 
      } 
     }; 
     Value = value; 
    } 
} 

ViewModel

public class SortedTreeViewWindowViewModel : PropertyChangedBase 
{ 
    private string _newValueString; 

    public string NewValueString 
    { 
     get { return _newValueString; } 
     set 
     { 
      _newValueString = value; 

      OnPropertyChanged("NewValueString"); 
     } 
    } 

    public TreeViewModel SelectedItem { get; set; } 

    public ObservableCollection<TreeViewModel> Items { get; set; } 

    public ICollectionView ItemsView { get; set; } 

    public SortedTreeViewWindowViewModel() 
    { 
     Items = new ObservableCollection<TreeViewModel>(); 
     ItemsView = new ListCollectionView(Items) { SortDescriptions = { new SortDescription("Value", ListSortDirection.Ascending) } }; 
    } 

    public void AddNewItem() 
    { 
     ObservableCollection<TreeViewModel> targetcollection; 

     //Insert the New Node as a Root node if nothing is selected. 
     targetcollection = SelectedItem == null ? Items : SelectedItem.Items; 

     if (_newValueString != null) 
     { 
      targetcollection.Add(new TreeViewModel(_newValueString)); 
      NewValueString = string.Empty; 
     } 
    } 
} 

View Code-Behind

public partial class Window1 : Window 
{ 
    public SortedTreeViewWindowViewModel ViewModel { get { return DataContext as SortedTreeViewWindowViewModel; } set { DataContext = value; } } 

    public Window1() 
    { 
     InitializeComponent(); 
     ViewModel = new SortedTreeViewWindowViewModel() 
      { 
       Items = {new TreeViewModel("Test")} 
      }; 
    } 

    private void AddNewItem(object sender, RoutedEventArgs e) 
    { 
     ViewModel.AddNewItem(); 
    } 

    private void OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) 
    { 
     ViewModel.SelectedItem = e.NewValue as TreeViewModel; 
    } 
} 

Спасибо так много е или помощь. Я надеюсь, что это поможет мне понять, как редактировать и создавать ViewModels, чтобы я мог научиться импровизировать немного больше в будущем.

UPDATE

TreeView теперь состоит из строк, так что часть решена. Тем не менее, мне по-прежнему нужна помощь с узлами по умолчанию. Я обновил свой код, чтобы отразить это изменение.

+0

Можете ли вы не просто изменить все объявления типа из int в строку? –

+0

Конечно, но я до сих пор не знаю, как бороться с дефолтом 'TreeViewItems' при запуске. –

+0

Еще один комментарий: я вижу, что вы новичок в MVVM, но имейте в виду, что при реализации MVVM вам редко нужен какой-либо код, кроме установки DataContext в ViewModel. –

ответ

3

Вот мои предложения

  • Изменение места, где у вас есть INT в строку. TreeView должен обработать это изменение.
  • В конструкторе ViewModel вручную вставляйте свои узлы по умолчанию. Убедитесь, что вы понимаете, как работать с TreeView, так как это повлияет на дизайн вашей модели и ViewModel и, естественно, улучшит реализацию.

Вот очень простой пример того, как заполнять дерево в ViewModel, который связан с TreeView в Вид:

Посмотреть

<Window x:Class="TreeViewExample.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <StackPanel> 
      <TreeView ItemsSource="{Binding Tree}"/> 
     </StackPanel> 
    </StackPanel> 
</Window> 

View Code-Behind

namespace TreeViewExample 
{ 
    using System.Windows; 

    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      DataContext = new MainWindowViewModel(); 
      InitializeComponent(); 
     } 
    } 
} 

ViewModel

namespace TreeViewExample 
{ 
    using System.Collections.ObjectModel; 
    using System.Windows.Controls; 

    class MainWindowViewModel 
    { 
     public ObservableCollection<TreeViewItem> Tree { get; set; } 

     public MainWindowViewModel() 
     { 
      Tree = new ObservableCollection<TreeViewItem>(); 
      Tree.Add(GetLoadedTreeRoot()); 
     } 

     private TreeViewItem GetLoadedTreeRoot() 
     { 
      TreeViewItem parent = new TreeViewItem() { Header = "Parent" }; 
      TreeViewItem child1 = new TreeViewItem() { Header = "Child 1" }; 
      TreeViewItem child2 = new TreeViewItem() { Header = "Child 2" }; 
      TreeViewItem grandchild1 = new TreeViewItem() { Header = "Grandchild 1" }; 
      TreeViewItem grandchild2 = new TreeViewItem() { Header = "Grandchild 2" }; 

      child1.Items.Add(grandchild1); 
      child2.Items.Add(grandchild2); 
      parent.Items.Add(child1); 
      parent.Items.Add(child2); 
      return parent; 
     } 
    } 
} 

Производит:

  • Родитель
    • Ребенок 1
      • Внук 1
    • Ребенок 2
      • Grandchild 2

Дополнительные мысли:

  • Чтобы очистить свой код-позади, вы можете посмотреть на реализацию команд, из которых Есть много. Хотя иногда вам это нужно, избегайте кода в коде, когда это возможно. Мне очень нравится this example, потому что он показывает вам общую реализацию MVVM, не входя в расширенные связанные с Command темы (ItemTemplates, пространство имен Interactivity и т. Д.).
+0

Большое спасибо. Для 'AddNewItem' мне нужно сделать что-то вроде:' Items.AddNewItem (новый TreeViewItem («Новый узел»)): «Или я в порядке? –

+0

@ TheRedLou Я знаю о командах, но я не предлагаю это начинающим, потому что это слишком много информации (привязка данных, ItemTemplates и т. Д.). И добавление ссылки на System.Windows.Interactivity для 'InvokeCommandAction' в случае событий усложняет его слишком много. –

+0

@Ericafterdark Обновлен мой ответ. –

Смежные вопросы