I have a TreeView. If it's relevant, i use MVVM and Caliburn Micro. I want that the selected node before the clearing will be selected after adding the node. I added DependencyProperty to the TreeView called TreeViewSelectedItemProperty for setting the SelectedItem property. see the code (NOTE: i simplified the code that would be easier to read):
In the ViewModel:
Nodes.Clear();
Nodes.Add(globalNode);
SelectedNode = node;
In the DependencyProperty file (TreeViewSelectedItemChanged method):
Collection<TreeViewItem> c=GetAllItemContainers(myTreeView);
foreach (var treeViewItem in c)
{
if (treeViewItem.DataContext == beforeClearingSelectedNode)
{
treeViewItem.IsSelected = true;
return;
}
}
Where GetAllItemContainers defined like this:
private static Collection<TreeViewItem> GetAllItemContainers(ItemsControl itemsControl)
{
Collection<TreeViewItem> allItems = new Collection<TreeViewItem>();
for (int i = 0; i < itemsControl.Items.Count; i++)
{
// try to get the item Container
TreeViewItem childItemContainer = itemsControl.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem;
// the item container maybe null if it is still not generated from the runtime
if (childItemContainer != null)
{
allItems.Add(childItemContainer);
Collection<TreeViewItem> childItems = GetAllItemContainers(childItemContainer);
foreach (TreeViewItem childItem in childItems)
{
allItems.Add(childItem);
}
}
}
return allItems;
}
The problem is that although the tree has 4 nodes, the size of the collection c is 1. I tried to use Loaded event of TreeView but also there the size of the collection was 1 when invoking. The size of the collection is correct (4) only when opening the view (The dependency property method TreeViewSelectedItemChanged is invoked. i debugged it and saw that c.Count() is 4).
Any help will be appreciated.
Have you tried creating a ViewModel for your nodes?
public class NodeViewModel : PropertyChangedBase
{
private bool isSelected;
public NodeViewModel(string displayName)
{
this.DisplayName = displayName;
this.Children = new ObservableCollection<NodeViewModel>();
}
public ObservableCollection<NodeViewModel> Children { get; private set; }
public string DisplayName { get; private set; }
public bool IsSelected
{
get { return this.isSelected; }
set
{
if (value.Equals(this.isSelected))
{
return;
}
this.isSelected = value;
this.NotifyOfPropertyChange(() => this.IsSelected);
Console.WriteLine(value);
}
}
}
You can bind your TreeViewItem
s to the ViewModels using a ItemContainerTemplate
:
<TreeView ItemsSource="{Binding Tree}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding DisplayName}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.