在所选项目上访问可观察集合中的项目

时间:2012-05-22 07:21:37

标签: c# wpf binding treeview observablecollection

我有一个使用hiarchialdatabinding的可观察集合填充的WPF TreeView 我需要访问我的observable集合中的项目或用于填充它的数据库。 示例用例是用户右键单击树视图项以添加子组。我显然需要访问其父级来添加子级。 有什么建议?我很失落..

我无法编辑树视图项本身,因此更改不会反映回我的数据库

数据库代码:

[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>

3 个答案:

答案 0 :(得分:0)

您可以将SelectedItem转换为LoginGroup

LoginGroup selectedGroup = (LoginGroup)groupView.SelectedItem;

答案 1 :(得分:0)

您应该使用TreeView的ItemContainer样式 这是示例TreeNode视图模型:

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

一些意见:

  • ViewModel是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。否则,将不会反映对节点集合所做的更改。

答案 2 :(得分:0)

您无法反映您的房产已发生变化,因为他们无法通知&#34;注意&#34;回来他们被编辑了。您需要从LoginGroup继承DependencyObject或实施INotifyPropertyChanged