2012-05-22 74 views
0

我有一個WPF TreeView由可觀察集合填充,使用hiarchialdatabinding 我需要訪問我的可觀察集合或用於填充它的數據庫中的項目。 示例用例是用戶右鍵單擊樹視圖項以添加子組。我顯然需要訪問它的父母來添加孩子。 有什麼建議嗎?我太失去了..在選定的項目中可觀察集合中的訪問項目

我不能只是編輯樹形視圖項目本身引起,則變化不會反射回我的數據庫

數據庫代碼:

[Serializable] 
public class LoginGroup 
{ 
    public string Name { get; set; } 
    public Guid ID { get; set; } 
    public List<Login> LoginItems = new List<Login>(); 
    public List<LoginGroup> Children { get; set; } 
} 

public static ObservableCollection<LoginGroup> _GroupCollection = new ObservableCollection<LoginGroup>(); 

public ObservableCollection<LoginGroup> GroupCollection 
{ 
    get { return _GroupCollection; } 
} 

的TreeView:

<TreeView x:Name="groupView" Width="211" TreeViewItem.Selected="OnTreeItemSelected" DockPanel.Dock="Left" Height="Auto" ItemsSource="{Binding GroupCollection}" > 
    <TreeView.ItemTemplate> 
     <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}"> 
      <TextBlock Text="{Binding Path=Name}" /> 
     </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView> 

回答

0

您可以將SelectedItem投射到LoginGroup

LoginGroup selectedGroup = (LoginGroup)groupView.SelectedItem; 
+0

這很多我知道,那不是我的問題。看最後一行。我不能編輯樹視圖項本身,因爲這些更改不會反映回我的數據庫 – Lexious

+0

@Lexi,我不是建議你編輯TreeView本身;在'selectedGroup'上執行所需的任何更改,然後將其保存到數據庫中......哪部分完全有問題? –

+0

嗯,這是我的問題..我不知道我將如何去找到我的方式,在數據庫中的項目,說它是一個孩子的孩子的孩子等孩子。我怎麼會去找到相同的在數據庫中的位置?我曾嘗試過使用獨特的標識符進行實驗,但沒有運氣 – Lexious

0

您應該使用TreeView的ItemContainer樣式。
這裏的樣本樹節點視圖模型:

public class TreeNode : ViewModel 
{ 
    public TreeNode() 
    { 
     this.children = new ObservableCollection<TreeNode>(); 

     // the magic goes here 
     this.addChildCommand = new RelayCommand(obj => AddNewChild()); 
    } 

    private void AddNewChild() 
    { 
     // create new child instance 
     var child = new TreeNode 
     { 
      Name = "This is a new child node.", 
      IsSelected = true // new child should be selected 
     }; 

     // add it to collection 
     children.Add(child); 

     // expand this node, we want to look at the new child node 
     IsExpanded = true; 
    } 

    public String Name 
    { 
     get { return name; } 
     set 
     { 
      if (name != value) 
      { 
       name = value; 
       OnPropertyChanged("Name"); 
      } 
     } 
    } 
    private String name; 

    public Boolean IsSelected 
    { 
     get { return isSelected; } 
     set 
     { 
      if (isSelected != value) 
      { 
       isSelected = value; 
       OnPropertyChanged("IsSelected"); 
      } 
     } 
    } 
    private Boolean isSelected; 

    public Boolean IsExpanded 
    { 
     get { return isExpanded; } 
     set 
     { 
      if (isExpanded != value) 
      { 
       isExpanded = value; 
       OnPropertyChanged("IsExpanded"); 
      } 
     } 
    } 
    private Boolean isExpanded; 

    public ObservableCollection<TreeNode> Children 
    { 
     get { return children; } 
    } 
    private ObservableCollection<TreeNode> children; 

    public ICommand AddChildCommand 
    { 
     get { return addChildCommand; } 
    } 
    private RelayCommand addChildCommand; 
} 

一些評論:

  • 視圖模型是任何基本實現INotifyPropertyChanged的 接口。
  • RelayCommand(a.k.a. DelegateCommand)是用於MVVM方法的ICommand實現。

這裏的觀點:

<Window x:Class="WpfApplication1.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"> 
    <TreeView ItemsSource="{Binding}"> 
     <TreeView.ItemContainerStyle> 
      <!-- Let's glue our view models with the view! --> 
      <Style TargetType="{x:Type TreeViewItem}"> 
       <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 
       <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /> 
       <Setter Property="ContextMenu"> 
        <Setter.Value> 
         <ContextMenu> 
          <!-- Here's menu item, which is responsible for adding new child node --> 
          <MenuItem Header="Add child..." Command="{Binding AddChildCommand}" /> 
         </ContextMenu> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </TreeView.ItemContainerStyle> 
     <TreeView.ItemTemplate> 
      <HierarchicalDataTemplate ItemsSource="{Binding Children}"> 
       <TextBlock Text="{Binding Name}"/> 
      </HierarchicalDataTemplate> 
     </TreeView.ItemTemplate> 
    </TreeView> 
</Window> 

...和樣本數據上下文初始化:

public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = new ObservableCollection<TreeNode> 
     { 
      new TreeNode { Name = "Root", IsSelected = true } 
     }; 
    } 

希望這有助於。

Upd
當然,您也必須將子節點公開爲ObservableCollection。否則,對節點集合所做的更改將不會反映出來。

+0

請原諒我的無知。但我不完全確定如何使用這樣的東西,即添加一個孩子,當在所選項目的上下文菜單中單擊完成。 – Lexious

+0

@Lexi,你也可以在ItemContainerStyle中定義上下文菜單。將item添加到菜單中,將item的命令綁定到視圖模型的任何ICommand屬性。然後,處理這個命令(編寫代碼添加子項)。 – Dennis

+0

@Lexi,我會更新我的答案,以便更清楚。 – Dennis

0

你不能反映你的屬性的變化,因爲他們沒有辦法「通知」他們被編輯。你需要從DependencyObject繼承LoginGroup或執行INotifyPropertyChanged

+0

因此,如果我實現INotifyPropertyChanged並通過groupView.SelectedItem更改數據,它應該自動爲r退後? – Lexious

+0

如果你的意思是改變屬性'名稱' - 是的。 – RredCat

+0

如果我需要將項目添加到列表子項中,該怎麼辦?這也會反映出來 – Lexious

相關問題