UWP TreeView编辑数据绑定的树项节点

时间:2019-07-17 09:43:19

标签: xaml uwp treeview editing items

在我正在使用的UWP TreeView上,我需要启用对treeview节点(项目)中文本的编辑。 Treeview已数据绑定到VM。双击或从VM发出命令即可启用编辑。使用TreeView上的ItemTemplateSelector定义项目。我需要类似的功能,例如WPF的DataGrid,该功能对其项目具有编辑和非编辑模式。

<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}"                    
        />

这是我需要启用编辑的文件模板项:

        <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 个答案:

答案 0 :(得分:0)

内置TreeViewItem不支持编辑,您可以尝试在WPDev UserVoice上提交功能请求。但是我认为还有很多其他简单的方法可以达到目标。

例如,您可以创建一个自定义UserControl来简单地实现它。

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

上面的代码示例只是我的简单实现。实际上,您可以只使用TextBox来显示文本。当'IsEditAble = false'时,您可以使它看起来像TextBlock。

然后,您可以直接使用此UserControl作为TreeViewItem的内容。

另一种方法是,您可以创建自定义TreeViewItem类并自己实现自定义样式。类似于XAML custom panels overview