2

In my WPF application, I want to add a TreeView control. The tree view control needs to be populated with items from database. So I bind the ItemsSource property to string collection.

Every item in the tree control can have from 0 to 32 child items. Again these items need to be binded. Each of these sub items should have a context menu with two options "Rename" and "Delete". How can I do this in WPF?

1 Answer 1

4

There are a few ways to do this. Here's one way that applies the context menu using a trigger that is bound to a property IsLeaf on the underlying view model.

MainWindow.xaml:

<Window x:Class="WpfScratch.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Window.Resources>

        <!-- the context menu for all tree view items -->
        <ContextMenu x:Key="TreeViewItemContextMenu">
            <MenuItem Header="Rename" />
            <MenuItem Header="Delete" />
        </ContextMenu>

        <!-- the data template for all tree view items -->
        <HierarchicalDataTemplate x:Key="TreeViewItemTemplate" ItemsSource="{Binding Nodes}">
            <TextBlock x:Name="TextBlock" Text="{Binding Text}" />
            <HierarchicalDataTemplate.Triggers>
                <DataTrigger Binding="{Binding IsLeaf}" Value="True">
                    <Setter TargetName="TextBlock" Property="ContextMenu" Value="{StaticResource TreeViewItemContextMenu}" />
                </DataTrigger>
            </HierarchicalDataTemplate.Triggers>
        </HierarchicalDataTemplate>

    </Window.Resources>

    <!-- the treeview -->
    <TreeView DataContext="{Binding TreeView}"
              ItemsSource="{Binding Nodes}"
              ItemTemplate="{StaticResource TreeViewItemTemplate}">
    </TreeView>

</Window>

MainWindow.xaml.cs:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowModel(
            new MainWindowTreeViewModel(
                new MainWindowTreeViewNodeModel(
                    "1",
                    new MainWindowTreeViewNodeModel("A"),
                    new MainWindowTreeViewNodeModel("B"),
                    new MainWindowTreeViewNodeModel("C")),
                new MainWindowTreeViewNodeModel(
                    "2",
                    new MainWindowTreeViewNodeModel("A"),
                    new MainWindowTreeViewNodeModel("B"),
                    new MainWindowTreeViewNodeModel("C")),
                new MainWindowTreeViewNodeModel(
                    "3",
                    new MainWindowTreeViewNodeModel("A"),
                    new MainWindowTreeViewNodeModel("B"),
                    new MainWindowTreeViewNodeModel("C"))));
    }
}

MainWindowModel.cs:

public class MainWindowModel
{
    public MainWindowModel(MainWindowTreeViewModel treeView)
    {
        TreeView = treeView;
    }

    public MainWindowTreeViewModel TreeView { get; private set; }
}

public class MainWindowTreeViewModel
{
    public MainWindowTreeViewModel(params MainWindowTreeViewNodeModel[] nodes)
    {
        Nodes = nodes.ToList().AsReadOnly();
    }

    public ReadOnlyCollection<MainWindowTreeViewNodeModel> Nodes { get; private set; }
}

public class MainWindowTreeViewNodeModel
{
    public MainWindowTreeViewNodeModel(string text, params MainWindowTreeViewNodeModel[] nodes)
    {
        Text = text;
        Nodes = nodes.ToList().AsReadOnly();
    }

    public string Text { get; private set; }
    public ReadOnlyCollection<MainWindowTreeViewNodeModel> Nodes { get; private set; }
    public bool IsLeaf { get { return Nodes.Count == 0; } }
}
Sign up to request clarification or add additional context in comments.

1 Comment

How do we do the renaming now? I have done it by display a mini dialog which takes the new name and applies the name to the child node but how to do it in place (within tree nodes???

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.