问题
I have a code that displays the files and folders names in a TreeView and put a checkbox from each element. What I don't know how to do is how to know the elements in the TreeView that are selected with the checkboxes.
XAML:
<TreeView Name="treeView" Grid.Row="10" Grid.ColumnSpan="3">
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Focusable="False" IsChecked="False" VerticalAlignment="Center"/>
<TextBlock Text="{Binding}" Margin="5,0" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
</TreeView>
Program:
DirectoryInfo di = new DirectoryInfo(folder);
treeView.Items.Add(getTree(di));
public TreeViewItem getTree(DirectoryInfo di)
{
TreeViewItem item = new TreeViewItem();
item.Header = di.Name;
item.FontWeight = FontWeights.Normal;
foreach (DirectoryInfo s in di.GetDirectories())
{
item.Items.Add(getTree(s));
}
foreach (FileInfo fi in di.GetFiles())
{
item.Items.Add(fi.Name);
}
return item;
}
回答1:
Create your own TreeViewItem
type:
public class Node
{
public string Name { get; set; }
public bool IsChecked { get; set; }
public List<Node> Children { get; } = new List<Node>();
}
Add instance of this type to the TreeView
:
public Node getTree(DirectoryInfo di)
{
Node item = new Node();
item.Name = di.Name;
foreach (DirectoryInfo s in di.GetDirectories())
{
item.Children.Add(getTree(s));
}
foreach (FileInfo fi in di.GetFiles())
{
item.Children.Add(new Node { Name = fi.Name });
}
return item;
}
Bind to the properties of this type in the view:
<TreeView Name="treeView" Grid.Row="10" Grid.ColumnSpan="3">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Node}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<CheckBox Focusable="False" IsChecked="{Binding IsChecked}" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Name}" Margin="5,0" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
You could then iterate through the items recursively and check the value of the IsChecked
property:
private List<string> GetSelectedNames()
{
List<string> selectedNames = new List<string>();
foreach (var item in treeView.Items.OfType<Node>())
GetSelected(item, ref selectedNames);
return selectedNames;
}
public void GetSelected(Node node, ref List<string> s)
{
if (node.IsChecked)
s.Add(node.Name);
foreach (Node child in node.Children)
GetSelected(child, ref s);
}
If you want to take this a step further, you bind the ItemsSource
property of the TreeView
to an IEnumerable<Node>
property of your view model and iterate through this one instead of the Items
property of the TreeView
control.
来源:https://stackoverflow.com/questions/46150421/treeview-with-checkboxes-dynamically-wpf-how-to-know-the-name-of-the-elements-s