UWP 从 TreeView 控件中获取选定节点 [英] UWP Get selected nodes from TreeView control
问题描述
如何从 TreeView
控件中获取当前突出显示/选定的节点?基于文档
我在 TreeView
控件上有一个事件处理程序:
事件处理程序应该循环遍历选定的节点,尽管我认为使用 SelectionMode="Single"
可枚举应该只有一项.
private void Tree_KeyDown(object sender, KeyRoutedEventArgs e){if (e.Key == Windows.System.VirtualKey.Delete){foreach(TreeDataBound.SelectedNodes 中的 var 元素){//删除项目}}}
SelectedNodes
似乎始终为空,即使突出显示了 TreeView iems 之一.在调试器中,SelectedNodes
显示为没有可访问属性的 System.__ComObject
类型,因此我无法进一步检查它.
对更好的方法有什么想法或建议吗?
UWP 从 TreeView 控件中获取选定的节点
对于单选模式.TreeViewItem
包含 IsSelected
属性,您可以使用 IsSelected
创建模型类并绑定它.项目选择后 IsSelected
值将被更改,因此您可以 foreach 项目源然后删除所选项目.请参考以下步骤.
背后的代码
公共密封部分类 MainPage : Page{公共主页(){this.InitializeComponent();数据源 = GetData();}私有 ObservableCollection数据源;私有 ObservableCollection获取数据(){var list = new ObservableCollection();ExplorerItem folder1 = new ExplorerItem(){Name = "工作文件",类型 = ExplorerItem.ExplorerItemType.Folder,儿童 ={新资源管理器项目(){Name = "功能规格",类型 = ExplorerItem.ExplorerItemType.Folder,儿童 ={新资源管理器项目(){Name = "TreeView 规格",类型 = ExplorerItem.ExplorerItemType.File,}}},新资源管理器项目(){Name = "功能时间表",类型 = ExplorerItem.ExplorerItemType.File,},新资源管理器项目(){Name = "总体项目计划",类型 = ExplorerItem.ExplorerItemType.File,},新资源管理器项目(){Name = "功能资源分配",类型 = ExplorerItem.ExplorerItemType.File,}}};ExplorerItem folder2 = new ExplorerItem(){Name = "个人文件夹",类型 = ExplorerItem.ExplorerItemType.Folder,儿童 ={新资源管理器项目(){Name = "家庭改造文件夹",类型 = ExplorerItem.ExplorerItemType.Folder,儿童 ={新资源管理器项目(){Name = "承包商联系方式",类型 = ExplorerItem.ExplorerItemType.File,},新资源管理器项目(){Name = "油漆配色方案",类型 = ExplorerItem.ExplorerItemType.File,},新资源管理器项目(){Name = "地板木纹类型",类型 = ExplorerItem.ExplorerItemType.File,},新资源管理器项目(){Name = "厨柜风格",类型 = ExplorerItem.ExplorerItemType.File,}}}}};list.Add(folder1);list.Add(folder2);退货清单;}私有无效 Tree_KeyDown(对象发送者,KeyRoutedEventArgs e){if (e.Key == Windows.System.VirtualKey.Delete){删除选择项(数据源);}}private ExplorerItem DeleteSelectItem(ObservableCollection DataSource){foreach(数据源中的变量项){如果(item.IsSelected == true){DataSource.Remove(item);归还物品;}var FindResult = DeleteSelectItem(item.Children);如果(查找结果!= null)返回查找结果;}返回空;}}公共类 ExplorerItem : INotifyPropertyChanged{公共事件 PropertyChangedEventHandler PropertyChanged;公共枚举 ExplorerItemType { 文件夹,文件 };公共字符串名称 { 获取;放;}公共资源管理器项目类型类型 { 获取;放;}私有 ObservableCollectionm_children;公共 ObservableCollection孩子们{得到{如果(m_children == null){m_children = new ObservableCollection();}返回 m_children;}放{m_children = 值;}}私人布尔 m_isExpanded;public bool IsExpanded{得到 { 返回 m_isExpanded;}放{如果(m_isExpanded != 值){m_isExpanded = 值;NotifyPropertyChanged("IsExpanded");}}}私人布尔 m_isSelected;public bool IsSelected{得到 { 返回 m_isSelected;}放{如果(m_isSelected != 值){m_isSelected = 值;NotifyPropertyChanged("IsSelected");}}}私有无效 NotifyPropertyChanged(String propertyName){if (PropertyChanged != null){PropertyChanged(this, new PropertyChangedEventArgs(propertyName));}}}类 ExplorerItemTemplateSelector : DataTemplateSelector{公共数据模板文件夹模板 { 获取;放;}公共数据模板 FileTemplate { 获取;放;}protected override DataTemplate SelectTemplateCore(object item){var explorerItem = (ExplorerItem)item;返回 explorerItem.Type == ExplorerItem.ExplorerItemType.Folder ?文件夹模板:文件模板;}}
Xaml
<DataTemplate x:Key="FolderTemplate" x:DataType="local:ExplorerItem"><树视图项AutomationProperties.Name="{x:绑定名称}"IsExpanded="{x:Bind IsExpanded,Mode=TwoWay}"IsSelected="{x:Bind IsSelected,Mode=TwoWay}"ItemsSource="{x:Bind Children}"><StackPanel Orientation="水平"><图像宽度=20"源=../Assets/folder.png"/><TextBlock Margin="0,0,10,0"/><TextBlock Text="{x:Bind Name}"/></StackPanel></TreeViewItem></数据模板><DataTemplate x:Key="FileTemplate" x:DataType="local:ExplorerItem"><TreeViewItem AutomationProperties.Name="{x:Bind Name}" IsSelected="{x:Bind IsSelected,Mode=TwoWay}"><StackPanel Orientation="水平"><图像宽度=20"源=../Assets/file.png"/><TextBlock Margin="0,0,10,0"/><TextBlock Text="{x:Bind Name}"/></StackPanel></TreeViewItem></数据模板><local:ExplorerItemTemplateSelectorx:Key="ExpolrerItemTemplateSelector"FileTemplate="{StaticResource FileTemplate}"FolderTemplate="{StaticResource FolderTemplate}"/></Page.Resources><网格><树视图x:Name="TreeDataBound"水平对齐=中心"垂直对齐=顶部"ItemTemplateSelector="{StaticResource ExpolrerItemTemplateSelector}"ItemsSource="{x:Bind DataSource,Mode=OneWay}"KeyDown="Tree_KeyDown"选择模式=单"/></网格>
有关完整的代码示例,请参阅此链接.
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屋!