UWP从TreeView控件获取选定的节点 [英] UWP Get selected nodes from TreeView control

查看:36
本文介绍了UWP从TreeView控件获取选定的节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从 TreeView 控件中获取当前突出显示/选定的节点?根据文档

我在 TreeView 控件上有一个事件处理程序:

 <代码>< controls:TreeView x:Name ="TreeDataBound"ItemsSource ="{绑定路径= TreeSource,模式= TwoWay}"ItemTemplateSelector ="{StaticResource TreeItemTemplateSelector}"SelectionMode ="Single"KeyDown ="Tree_KeyDown"> 

事件处理程序应该遍历选定的节点,尽管我认为使用 SelectionMode ="Single" 时,可枚举应该只有一个项目.

 私有无效Tree_KeyDown(对象发送者,KeyRoutedEventArgs e){如果(e.Key == Windows.System.VirtualKey.Delete){foreach(TreeDataBound.SelectedNodes中的var元素){//删除项目}}} 

SelectedNodes 似乎始终为空,即使突出显示TreeView元素之一也是如此.在调试器中, SelectedNodes 显示为 System .__ ComObject 的类型,没有可访问的属性,因此我无法对其进行进一步检查.

对更好的方法有任何想法或建议吗?

解决方案

UWP从TreeView控件中获取选定的节点

用于单选模式. TreeViewItem 包含 IsSelected 属性,您可以使用 IsSelected 创建模型类并将其绑定.选定项目后, IsSelected 的值将被更改,因此您可以为每个项目源添加一个,然后删除选定的项目.请参考以下步骤.

背后的代码

 公共密封的局部类MainPage:页面{公共MainPage(){this.InitializeComponent();DataSource = GetData();}私有ObservableCollection< ExplorerItem>数据源;私有ObservableCollection< ExplorerItem>GetData(){var list = new ObservableCollection< ExplorerItem>();ExplorerItem folder1 =新的ExplorerItem(){名称=工作文件",类型= ExplorerItem.ExplorerItemType.Folder,儿童={新的ExplorerItem(){名称=功能规格",类型= ExplorerItem.ExplorerItemType.Folder,儿童={新的ExplorerItem(){名称="TreeView规范",类型= ExplorerItem.ExplorerItemType.File,}}},新的ExplorerItem(){名称=功能时间表",类型= ExplorerItem.ExplorerItemType.File,},新的ExplorerItem(){名称=总体项目计划",类型= ExplorerItem.ExplorerItemType.File,},新的ExplorerItem(){名称=功能资源分配",类型= ExplorerItem.ExplorerItemType.File,}}};ExplorerItem folder2 =新的ExplorerItem(){名称=个人文件夹",类型= ExplorerItem.ExplorerItemType.Folder,儿童={新的ExplorerItem(){名称=家庭装修文件夹",类型= ExplorerItem.ExplorerItemType.Folder,儿童={新的ExplorerItem(){名称=承包商联系信息",类型= ExplorerItem.ExplorerItemType.File,},新的ExplorerItem(){名称=绘画配色方案",类型= ExplorerItem.ExplorerItemType.File,},新的ExplorerItem(){名称=地板木纹类型",类型= ExplorerItem.ExplorerItemType.File,},新的ExplorerItem(){名称=厨房橱柜风格",类型= ExplorerItem.ExplorerItemType.File,}}}}};list.Add(folder1);list.Add(folder2);返回清单;}私有void Tree_KeyDown(对象发送者,KeyRoutedEventArgs e){如果(e.Key == Windows.System.VirtualKey.Delete){DeleteSelectItem(DataSource);}}私有ExplorerItem DeleteSelectItem(ObservableCollection< ExplorerItem>数据源){foreach(数据源中的var项){如果(item.IsSelected == true){DataSource.Remove(item);归还物品;}var FindResult = DeleteSelectItem(item.Children);如果(FindResult!= null)返回FindResult;}返回null;}}公共类ExplorerItem:INotifyPropertyChanged{公共事件PropertyChangedEventHandler PropertyChanged;公共枚举ExplorerItemType {文件夹,文件};公共字符串名称{get;放;}公共ExplorerItemType类型{放;}私有ObservableCollection< ExplorerItem>m_children;公共ObservableCollection< ExplorerItem>孩子们{得到{如果(m_children == null){m_children = new ObservableCollection< ExplorerItem>();}返回m_children;}放{m_children =值;}}私人布尔m_isExpanded;公共布尔IsExpanded{得到{return m_isExpanded;}放{如果(m_isExpanded!=值){m_isExpanded =值;NotifyPropertyChanged("IsExpanded");}}}私人布尔m_isSelected;公共布尔IsSelected{得到{return m_isSelected;}放{如果(m_isSelected!=值){m_isSelected =值;NotifyPropertyChanged("IsSelected");}}}私有void NotifyPropertyChanged(String propertyName){如果(PropertyChanged!= null){PropertyChanged(this,new PropertyChangedEventArgs(propertyName));}}}类ExplorerItemTemplateSelector:DataTemplateSelector{公共DataTemplate FolderTemplate {放;}公共DataTemplate FileTemplate {放;}受保护的重写DataTemplate SelectTemplateCore(对象项){var explorerItem =(ExplorerItem)item;返回explorerItem.Type == ExplorerItem.ExplorerItemType.Folder吗?FolderTemplate:FileTemplate;}} 

Xaml

 < Page.Resources>< DataTemplate x:Key ="FolderTemplate" x:DataType ="local:ExplorerItem">< TreeViewItemAutomationProperties.Name ="{x:绑定名称}"IsExpanded ="{x:Bind IsExpanded,Mode = TwoWay}"IsSelected ="{x:Bind IsSelected,Mode = TwoWay}"ItemsSource ="{x:绑定儿童}">< StackPanel Orientation ="Horizo​​ntal"><图片宽度="20"源= ../Assets/folder.png"/>< TextBlock Margin ="0,0,10,0"/>< TextBlock Text ="{x:绑定名称}"/></StackPanel></TreeViewItem></DataTemplate>< DataTemplate x:Key ="FileTemplate" x:DataType ="local:ExplorerItem">< TreeViewItem AutomationProperties.Name ="{x:Bind Name}" IsSelected ="{x:Bind IsSelected,Mode = TwoWay}">< StackPanel Orientation ="Horizo​​ntal"><图片宽度="20"源= ../Assets/file.png"/>< TextBlock Margin ="0,0,10,0"/>< TextBlock Text ="{x:绑定名称}"/></StackPanel></TreeViewItem></DataTemplate>< local:ExplorerItemTemplateSelectorx:Key ="ExpolrerItemTemplateSelector"FileTemplate ="{StaticResource FileTemplate}"FolderTemplate ="{StaticResource FolderTemplate}"/></Page.Resources><网格>< TreeViewx:Name ="TreeDataBound"Horizo​​ntalAlignment ="Center"VerticalAlignment =顶部"ItemTemplateSelector ="{StaticResource ExpolrerItemTemplateSelector}"ItemsSource ="{x:Bind DataSource,Mode = OneWay}"KeyDown ="Tree_KeyDown"SelectionMode ="Single"/></Grid> 

有关完整的代码示例,请参阅此链接.

How do you get the currently highlighted/selected node from a TreeView control? Based on the documentation here it should be possible to iterate through the control's SelectedNodes property but its always empty.


EDIT: This turns out to be an actual bug with XAML, tracked here. Until it's fixed, the accepted answer does fine as work-around.


Context: I'm working on a simple demo application to explore the TreeView control. I'm trying to add a keyboard shortcut to delete the currently active/selected node. I have the delete functionality in a RelayCommand class that implements ICommand. I have already gotten it working from the TreeViewItem DataTemplate as a button and as a flyout menu. I couldn't see a clean way to reuse the ICommand in a keyboard shortcut.

Image of the app with the last-clicked item highlighted; I need to access this TreeViewItem in the code-behind so I can delete it when the TreeView has focus and the "Delete" key is pressed.

I have an event handler on the TreeView control:

<controls:TreeView x:Name="TreeDataBound"
    ItemsSource="{Binding Path=TreeSource, Mode=TwoWay}"
    ItemTemplateSelector="{StaticResource TreeItemTemplateSelector}"
    SelectionMode="Single"
    KeyDown="Tree_KeyDown">

The event handler should be looping through the selected nodes, although I think with SelectionMode="Single" the enumerable should only have one item.

private void Tree_KeyDown(object sender, KeyRoutedEventArgs e)
{
    if (e.Key == Windows.System.VirtualKey.Delete)
    {
        foreach (var element in TreeDataBound.SelectedNodes)
        {
            // Delete the item 
        }
    }
}

SelectedNodes appears to always be empty, even when one of the TreeView iems is highlighted. In the debugger SelectedNodes appears as type of System.__ComObject with no accessible properties, so I can't inspect it any further.

Any thoughts or suggestions for a better approach?

解决方案

UWP Get selected nodes from TreeView control

For Single Selection mode. TreeViewItem contains IsSelected property, you could create model class with IsSelected and bind it. After item selected IsSelected value will be changed, so you could foreach the itemsource then delete the selected item. Please refer the following steps.

Code behind

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        DataSource = GetData();
    }
    private ObservableCollection<ExplorerItem> DataSource;
    private ObservableCollection<ExplorerItem> GetData()
    {
        var list = new ObservableCollection<ExplorerItem>();
        ExplorerItem folder1 = new ExplorerItem()
        {
            Name = "Work Documents",
            Type = ExplorerItem.ExplorerItemType.Folder,
            Children =
            {
                new ExplorerItem()
                {
                    Name = "Functional Specifications",
                    Type = ExplorerItem.ExplorerItemType.Folder,
                    Children =
                    {
                        new ExplorerItem()
                        {
                            Name = "TreeView spec",
                            Type = ExplorerItem.ExplorerItemType.File,
                          }
                    }
                },
                new ExplorerItem()
                {
                    Name = "Feature Schedule",
                    Type = ExplorerItem.ExplorerItemType.File,
                },
                new ExplorerItem()
                {
                    Name = "Overall Project Plan",
                    Type = ExplorerItem.ExplorerItemType.File,
                },
                new ExplorerItem()
                {
                    Name = "Feature Resources Allocation",
                    Type = ExplorerItem.ExplorerItemType.File,
                }
            }
        };
        ExplorerItem folder2 = new ExplorerItem()
        {
            Name = "Personal Folder",
            Type = ExplorerItem.ExplorerItemType.Folder,
            Children =
                    {
                        new ExplorerItem()
                        {
                            Name = "Home Remodel Folder",
                            Type = ExplorerItem.ExplorerItemType.Folder,
                            Children =
                            {
                                new ExplorerItem()
                                {
                                    Name = "Contractor Contact Info",
                                    Type = ExplorerItem.ExplorerItemType.File,
                                },
                                new ExplorerItem()
                                {
                                    Name = "Paint Color Scheme",
                                    Type = ExplorerItem.ExplorerItemType.File,
                                },
                                new ExplorerItem()
                                {
                                    Name = "Flooring Woodgrain type",
                                    Type = ExplorerItem.ExplorerItemType.File,
                                },
                                new ExplorerItem()
                                {
                                    Name = "Kitchen Cabinet Style",
                                    Type = ExplorerItem.ExplorerItemType.File,
                                }
                            }
                        }
                    }
        };

        list.Add(folder1);
        list.Add(folder2);
        return list;
    }

    private void Tree_KeyDown(object sender, KeyRoutedEventArgs e)
    {
        if (e.Key == Windows.System.VirtualKey.Delete)
        {
             DeleteSelectItem(DataSource);
        }

    }
    private ExplorerItem DeleteSelectItem(ObservableCollection<ExplorerItem> DataSource)
    {
        foreach (var item in DataSource)
        {
            if (item.IsSelected == true)
            {
                DataSource.Remove(item);
                return item;
            }

            var FindResult = DeleteSelectItem(item.Children);
            if (FindResult != null)
                return FindResult;
        }

        return null;
    }
}
public class ExplorerItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public enum ExplorerItemType { Folder, File };
    public String Name { get; set; }
    public ExplorerItemType Type { get; set; }
    private ObservableCollection<ExplorerItem> m_children;
    public ObservableCollection<ExplorerItem> Children
    {
        get
        {
            if (m_children == null)
            {
                m_children = new ObservableCollection<ExplorerItem>();
            }
            return m_children;
        }
        set
        {
            m_children = value;
        }
    }

    private bool m_isExpanded;
    public bool IsExpanded
    {
        get { return m_isExpanded; }
        set
        {
            if (m_isExpanded != value)
            {
                m_isExpanded = value;
                NotifyPropertyChanged("IsExpanded");
            }
        }
    }

    private bool m_isSelected;
    public bool IsSelected
    {
        get { return m_isSelected; }

        set
        {
            if (m_isSelected != value)
            {
                m_isSelected = value;
                NotifyPropertyChanged("IsSelected");
            }
        }

    }

    private void NotifyPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

class ExplorerItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate FolderTemplate { get; set; }
    public DataTemplate FileTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        var explorerItem = (ExplorerItem)item;
        return explorerItem.Type == ExplorerItem.ExplorerItemType.Folder ? FolderTemplate : FileTemplate;
    }
}

Xaml

<Page.Resources>
    <DataTemplate x:Key="FolderTemplate" x:DataType="local:ExplorerItem">
        <TreeViewItem
            AutomationProperties.Name="{x:Bind Name}"
            IsExpanded="{x:Bind IsExpanded,Mode=TwoWay}"
            IsSelected="{x:Bind IsSelected,Mode=TwoWay}"
            ItemsSource="{x:Bind Children}"
            >

            <StackPanel Orientation="Horizontal">
                <Image Width="20" Source="../Assets/folder.png" />
                <TextBlock Margin="0,0,10,0" />
                <TextBlock Text="{x:Bind Name}" />
            </StackPanel>
        </TreeViewItem>
    </DataTemplate>

    <DataTemplate x:Key="FileTemplate" x:DataType="local:ExplorerItem">
        <TreeViewItem AutomationProperties.Name="{x:Bind Name}" IsSelected="{x:Bind IsSelected,Mode=TwoWay}">

            <StackPanel Orientation="Horizontal">
                <Image Width="20" Source="../Assets/file.png" />
                <TextBlock Margin="0,0,10,0" />
                <TextBlock Text="{x:Bind Name}" />
            </StackPanel>
        </TreeViewItem>
    </DataTemplate>

    <local:ExplorerItemTemplateSelector
        x:Key="ExpolrerItemTemplateSelector"
        FileTemplate="{StaticResource FileTemplate}"
        FolderTemplate="{StaticResource FolderTemplate}"
        />
</Page.Resources>
<Grid>
    <TreeView
        x:Name="TreeDataBound"
        HorizontalAlignment="Center"
        VerticalAlignment="Top"
        ItemTemplateSelector="{StaticResource ExpolrerItemTemplateSelector}"
        ItemsSource="{x:Bind DataSource,Mode=OneWay}"
        KeyDown="Tree_KeyDown"
        SelectionMode="Single"
        />
</Grid>

For the complete code sample please refer this link.

这篇关于UWP从TreeView控件获取选定的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆