I'm using version 1.0.1.0 (Q2 2008 we believe) of the TreeView control. The hierarchy represented in the control is not bindable throughout, so we are forced to manually refresh it from time to time, and we also need to re-select the selected item after a refresh. The code is a bit complicated, but it seems to work well enough. It's called after PlansTreeView.Items.Refresh().
We also need to have some of the nodes sorted, and that code works well and seems simple enough:
The trouble is that once a node is sorted, I can no longer refresh it (regardless of my Reselection - PlansTreeView.Items.Refresh() just does nothing). Is there something going on in the control that disables refreshing once I have it sorted? Or are there other approaches I should be taking towards refreshing the tree?
private void ReselectTreeViewSelection() |
{ |
if (PlansTreeView.SelectedItem == null) |
return; |
var initialSelection = PlansTreeView.SelectedItem; |
// find the master for the current selection |
var selectedMaster = initialSelection as MasterRetailPlan; |
if (selectedMaster == null) |
{ |
var selectedTier = initialSelection as TierRetailPlan; |
if (selectedTier != null) |
selectedMaster = selectedTier.Master; |
else |
{ |
var selectedPub = (PublicationRetailPlan)initialSelection; |
selectedMaster = selectedPub.Tier.Master; |
} |
} |
// find the matching master whether placeholder or otherwise |
var master = PlansTreeView.Items.Cast<MasterRetailPlan>().Single(x => x.ToString() == selectedMaster.Name || x.Name == selectedMaster.Name); |
_masterContainer = PlansTreeView.ContainerFromItemRecursive(master); |
// if the selected item was a master, then we're done |
if (selectedMaster == initialSelection) |
_masterContainer.IsSelected = true; |
else |
// we know we haven't found the selected item yet, so we expand the master |
// and dig in to the tiers as soon as the ItemContainers for the tiers have been created |
// we do this because the containers won't be created until needed, i.e. until the parent is expanded |
_masterContainer.ItemContainerGenerator.StatusChanged += MasterContainerGenerator_StatusChanged; |
_masterContainer.IsExpanded = true; |
} |
void MasterContainerGenerator_StatusChanged(object sender, EventArgs e) |
{ |
// don't do anything until the containers are generated |
var generator = sender as ItemContainerGenerator; |
if (generator.Status != GeneratorStatus.ContainersGenerated) |
return; |
// find the tier for the current selection |
var initialSelection = PlansTreeView.SelectedItem; |
var selectedTier = initialSelection as TierRetailPlan; |
if (selectedTier == null) |
{ |
var selectedPub = initialSelection as PublicationRetailPlan; |
if (selectedPub != null) |
selectedTier = selectedPub.Tier; |
} |
// find the matching tier |
var tier = _masterContainer.Items.Cast<TierRetailPlan>().Single(x => x.Name == selectedTier.Name); |
_tierContainer = PlansTreeView.ContainerFromItemRecursive(tier); |
// if the selected item was the tier, then we're done |
if (selectedTier == initialSelection) |
_tierContainer.IsSelected = true; |
else |
// we know the tier wasn't the selected item, so it must be a pub |
// we expand the tier and examine the pubs as soon as their ItemContainers have been created |
_tierContainer.ItemContainerGenerator.StatusChanged += TierContainerGenerator_StatusChanged; |
_tierContainer.IsExpanded = true; |
} |
void TierContainerGenerator_StatusChanged(object sender, EventArgs e) |
{ |
// don't do anything until Generated |
var generator = sender as ItemContainerGenerator; |
if (generator.Status != GeneratorStatus.ContainersGenerated) |
return; |
// we know if this fired, then the selected item was a pub |
var selectedPub = (PublicationRetailPlan)PlansTreeView.SelectedItem; |
var pub = _tierContainer.Items.Cast<PublicationRetailPlan>().Single(x => x.Name == selectedPub.Name); |
var pubContainer = PlansTreeView.ContainerFromItemRecursive(pub); |
pubContainer.IsSelected = true; |
} |
We also need to have some of the nodes sorted, and that code works well and seems simple enough:
private void PlansTreeView_Expanded(object sender, RadRoutedEventArgs e) |
{ |
var item = (RadTreeViewItem)e.OriginalSource; |
var tier = (item.DataContext as TierRetailPlan); |
if (tier == null) |
return; |
if (item.Items.SortDescriptions.Count == 0) |
item.Items.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending)); |
} |
The trouble is that once a node is sorted, I can no longer refresh it (regardless of my Reselection - PlansTreeView.Items.Refresh() just does nothing). Is there something going on in the control that disables refreshing once I have it sorted? Or are there other approaches I should be taking towards refreshing the tree?