添加"额外"节点到XAML TreeView

时间:2014-07-15 13:35:32

标签: c# silverlight xaml mvvm treeview

使用MVVM模式,我试图在XAML中构建一个看起来像这样的TreeView(请注意,括号内的项目实际上代表了按钮):

- [Edit] [Delete] Location 1
    - [Edit] [Delete] Location 1, Project 1
    - [Edit] [Delete] Location 1, Project 2
    - [Edit] [Delete] Location 1, Project 3
    - [New Project]
- [Edit] [Delete] Location 2
    - [Edit] [Delete] Location 2, Project 1
    - [New Project]
- [Edit] [Delete] Location 3
    - [Edit] [Delete] Location 3, Project 1
    - [Edit] [Delete] Location 3, Project 2
    - [New Project]
- [New Location]

这个想法是TreeView中的每个节点在标题文本旁边都有两个按钮,用户可以单击这些按钮来删除/编辑节点。然后,在每个"组的底部"项目中有一个[New Project]按钮,可以点击该按钮将新项目添加到" group"。最后,在整个TreeView的底部有一个[New Location]按钮,这样就可以添加一个新的Location节点。

我已正确布置TreeView和[新位置]按钮,但无法弄清楚如何将[新建项目]按钮添加到每个位置的项目组底部。我尝试过使用多个嵌套的TreeView控件,但分组和滚动似乎没有按预期运行。

这是我的MainPageView代码:

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  x:Class="SilverlightApplication2.MainPageView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:silverlightApplication2="clr-namespace:SilverlightApplication2"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.DataContext>
        <silverlightApplication2:MainPageViewModel/>
    </UserControl.DataContext>

    <StackPanel Orientation="Vertical">
        <sdk:TreeView ItemsSource="{Binding Locations}" BorderBrush="Transparent">
            <sdk:TreeView.ItemTemplate>
                <sdk:HierarchicalDataTemplate ItemsSource="{Binding Projects}">
                    <StackPanel Orientation="Horizontal">
                        <Button Margin="2">
                            <Image Source="edit.png"/>
                            <ToolTipService.ToolTip>
                                <ToolTip Content="Edit item"/>
                            </ToolTipService.ToolTip>
                        </Button>
                        <Button Margin="2">
                            <Image Source="delete.png"/>
                            <ToolTipService.ToolTip>
                                <ToolTip Content="Delete item"/>
                            </ToolTipService.ToolTip>
                        </Button>
                        <sdk:TreeViewItem Header="{Binding Name}"/>
                    </StackPanel>
                </sdk:HierarchicalDataTemplate>
            </sdk:TreeView.ItemTemplate>
        </sdk:TreeView>
        <Button Margin="30,0,0,0" Height="23" Width="23" HorizontalAlignment="Left">
            <Image Source="green-plus-sign-md.png"></Image>
            <ToolTipService.ToolTip>
                <ToolTip Content="Add new location"/>
            </ToolTipService.ToolTip>
        </Button>
    </StackPanel>
</UserControl>

这是我的MainPageViewModel代码:

using System.Collections.ObjectModel;

namespace SilverlightApplication2
{
    public class MainPageViewModel
    {
        #region Constructors

        public MainPageViewModel()
        {
            this.Locations = new ObservableCollection<LocationViewModel>
                                 {
                                     new LocationViewModel
                                         {
                                             Name = "Location 1",
                                             Projects = new ObservableCollection<ProjectViewModel>
                                                            {
                                                                new ProjectViewModel { Name = "Location 1 - Project 1"},
                                                                new ProjectViewModel { Name = "Location 1 - Project 2"},
                                                                new ProjectViewModel { Name = "Location 1 - Project 3"},
                                                                new ProjectViewModel { Name = "Location 1 - Project 4"},
                                                            }
                                         },
                                     new LocationViewModel
                                         {
                                             Name = "Location 2",
                                             Projects = new ObservableCollection<ProjectViewModel>
                                                            {
                                                                new ProjectViewModel { Name = "Location 2 - Project 1"},
                                                                new ProjectViewModel { Name = "Location 2 - Project 2"}
                                                            }
                                         },
                                     new LocationViewModel
                                         {
                                             Name = "Location 3",
                                             Projects = new ObservableCollection<ProjectViewModel>
                                                            {
                                                                new ProjectViewModel { Name = "Location 3 - Project 1"},
                                                                new ProjectViewModel { Name = "Location 3 - Project 2"},
                                                                new ProjectViewModel { Name = "Location 3 - Project 3"},
                                                                new ProjectViewModel { Name = "Location 3 - Project 4"},
                                                                new ProjectViewModel { Name = "Location 3 - Project 5"},
                                                                new ProjectViewModel { Name = "Location 3 - Project 6"},
                                                                new ProjectViewModel { Name = "Location 3 - Project 7"}
                                                            }
                                         }
                                 };
        }

        #endregion

        #region Properties

        public ObservableCollection<LocationViewModel> Locations { get; set; } 

        #endregion
    }
}

这是LocationViewModelCode:

using System.Collections.ObjectModel;
using Microsoft.Practices.Prism.ViewModel;


namespace SilverlightApplication2
{
    public class LocationViewModel : NotificationObject
    {
        #region Properties

        public string Name { get; set; }

        public ObservableCollection<ProjectViewModel> Projects { get; set; }

        #endregion
    }
}

最后,ProjectViewModel代码:

namespace SilverlightApplication2
{
    public class ProjectViewModel
    {
        #region Properties

        public string Name { get; set; }

        #endregion
    }
}

正如您所看到的,我在Silverlight中这样做,但如果有人知道如何做到这一点,WPF解决方案可能会同样好。

我也意识到这可以通过代码隐藏很容易地完成,但我试图坚持MVVM模式并找到一种纯粹在XAML中执行此操作的方法。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我概括了树节点的视图模型。

可能有IsLocation,IsProject和HasContent属性。

HasContent属性可以控制节点是否显示&#39; New ...&#39;链接。然后,您可以检查该链接的命令中的类型。

如果您不想拥有IsLocation和IsProject,您可以为树节点使用抽象基类,并从中继承两种类型。两者都具有相似的HasContent逻辑,然后为&#39; New&#39;提供不同的命令。逻辑。

答案 1 :(得分:0)

也许对架构的重新思考会有所帮助吗?

我个人认为这个新项目&#39;操作是对Location对象的操作,而不是Projects集合中的操作。既然如此,您的新项目&#39;按钮可能位于edit根目录的deleteLocation按钮上。

也许不是对你的问题的直接回答,而是对它的侧面方法。