2
votes

On the UWP TreeView I'm working on I need to enable editing of text in the treeview node (item). Treeview is databinded to VM. Editing shoul be enabled by doubleclicking or by raising command from VM. Items are defined with ItemTemplateSelector on TreeView. I would need similar functionality like DataGrid from WPF that have editing and non-editing modes for it's items.

<TreeView Style="{StaticResource MyTreeViewStyle1}" 
        x:Name="treeviewMain" 
        Grid.Row="1" 
        ItemsSource="{x:Bind ViewModel.storageFolders, Mode=TwoWay}"      
        ItemTemplateSelector="{StaticResource ExplorerItemTemplateSelector}" ItemContainerStyle="{StaticResource MyTreeViewItemStyle}" />

ItemTemplateSelector:

      <local:ExplorerItemTemplateSelector
        x:Key="ExplorerItemTemplateSelector"
        FolderTemplate="{StaticResource FolderTemplate}"
        FileTemplate="{StaticResource FileTemplate}" 
        InactiveTemplate="{StaticResource InactiveTemplate}"
        TrashTemplate="{StaticResource TrashTemplate}"                    
        />

And here is the File template item that I need to be edit enabled:

        <DataTemplate x:Key="FileTemplate" x:DataType="local:FolderInfo">
        <local:ExtraTreeViewItem>
            <StackPanel Orientation="Horizontal">
                <Image Width="20" Source="Assets/file.png"/>
                <TextBlock Text="{Binding FolderName}"/>
            </StackPanel>
        </local:ExtraTreeViewItem>
    </DataTemplate>
1

1 Answers

1
votes

The built-in TreeViewItem doesn't support edit, you could try to submit a Feature Request on WPDev UserVoice. But I think there're many other simple ways to get your target.

For example, you could make a custom UserControl to achieve it simply.

<UserControl
x:Class="AppTreeView.EditableControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppTreeView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<StackPanel Orientation="Horizontal">
    <Image x:Name="img" Width="20" Source="Assets/file.png" />
    <TextBlock x:Name="txb" Height="30"></TextBlock>
    <TextBox x:Name="textbox" Visibility="Collapsed" Height="30"></TextBox>
</StackPanel>

public sealed partial class EditableControl : UserControl
{
    public EditableControl()
    {
        this.InitializeComponent();
        this.DoubleTapped += EditableControl_DoubleTapped;
        this.textbox.TextChanged += Textbox_TextChanged;
    }

    private void Textbox_TextChanged(object sender, TextChangedEventArgs e)
    {
        this.FolderName = textbox.Text;
    }

    private void EditableControl_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        IsEditAble = true;
    }

    public string FolderName
    {
        get { return (string)GetValue(FolderNameProperty); }
        set { SetValue(FolderNameProperty, value); }
    }

    // Using a DependencyProperty as the backing store for FolderName.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FolderNameProperty =
        DependencyProperty.Register("FolderName", typeof(string), typeof(EditableControl), new PropertyMetadata(null, FolderNamePropertyChangedCallback));


    public bool IsEditAble
    {
        get { return (bool)GetValue(IsEditAbleProperty); }
        set { SetValue(IsEditAbleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsEditAble.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsEditAbleProperty =
        DependencyProperty.Register("IsEditAble", typeof(bool), typeof(EditableControl), new PropertyMetadata(false, IsEditAblePropertyChangedCallback));

    public static void IsEditAblePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue != e.OldValue)
        {
            if ((bool)e.NewValue == true)
            {
                ((EditableControl)d).textbox.Visibility = Visibility.Visible;
                ((EditableControl)d).txb.Visibility = Visibility.Collapsed;
            }
            else
            {
                ((EditableControl)d).textbox.Visibility = Visibility.Collapsed;
                ((EditableControl)d).txb.Visibility = Visibility.Visible;
            }
        }
    }

    public static void FolderNamePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue != e.OldValue)
        {
            ((EditableControl)d).textbox.Text = e.NewValue.ToString();
            ((EditableControl)d).txb.Text = e.NewValue.ToString();
        }
    }
}

The above code sample just is my simple implementation. Actually, you could just use the TextBox to show the text. You could make it looks like the TextBlock when 'IsEditAble=false'.

Then, you could directly use this UserControl as the TreeViewItem's content.

Another way is you could make a custom TreeViewItem class and implement the custom style by yourself. It's similar to XAML custom panels overview.