Ispirato dalla risposta di Fëanor, ho tentato di fare il TreeViewItem
facilmente accessibile per ogni elemento di dati che un TreeViewItem
è stato creato per.
L'idea è quella di aggiungere un campo -typed TreeViewItem
al modello vista, esposto anche tramite un'interfaccia, e hanno la TreeView
popolare automaticamente ogni volta che si crea il contenitore TreeViewItem
.
Questo viene fatto sottoclasse TreeView
e allegando un evento allo ItemContainerGenerator
, che registra lo TreeViewItem
ogni volta che viene creato. I trucchi includono il fatto che i numeri TreeViewItem
vengono creati pigramente, quindi potrebbe non essere disponibile in determinati orari.
Da quando ho postato questa risposta, l'ho sviluppata ulteriormente e l'ho usata a lungo in un progetto. Nessun problema finora, a parte il fatto che questo violi MVVM (ma ti risparmia anche un sacco di dati per i casi semplici). Fonte here.
Uso
Selezionare il padre della voce selezionata e comprimerlo, assicurando che è nella vista:
...
var selected = myTreeView.SelectedItem as MyItem;
selected.Parent.TreeViewItem.IsSelected = true;
selected.Parent.TreeViewItem.IsExpanded = false;
selected.Parent.TreeViewItem.BringIntoView();
...
dichiarazioni:
<Window ...
xmlns:tvi="clr-namespace:TreeViewItems"
...>
...
<tvi:TreeViewWithItem x:Name="myTreeView">
<HierarchicalDataTemplate DataType = "{x:Type src:MyItem}"
ItemsSource = "{Binding Children}">
<TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
</tvi:TreeViewWithItem>
...
</Window>
class MyItem : IHasTreeViewItem
{
public string Name { get; set; }
public ObservableCollection<MyItem> Children { get; set; }
public MyItem Parent;
public TreeViewItem TreeViewItem { get; set; }
...
}
Codice
public class TreeViewWithItem : TreeView
{
public TreeViewWithItem()
{
ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
}
private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
var generator = sender as ItemContainerGenerator;
if (generator.Status == GeneratorStatus.ContainersGenerated)
{
int i = 0;
while (true)
{
var container = generator.ContainerFromIndex(i);
if (container == null)
break;
var tvi = container as TreeViewItem;
if (tvi != null)
tvi.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
var item = generator.ItemFromContainer(container) as IHasTreeViewItem;
if (item != null)
item.TreeViewItem = tvi;
i++;
}
}
}
}
interface IHasTreeViewItem
{
TreeViewItem TreeViewItem { get; set; }
}
fonte
2012-03-26 13:33:13
@romkyns: Cosa? Questa domanda non ha * * nulla a che fare con il tenere traccia dell'elemento selezionato. –
@romkyns: beh, non dovresti prendere TreeViewItem in primo luogo, quindi non importa se è difficile da fare o meno. –
@ H.B. Potrebbe essere così ... forse [puoi aiutarmi a farlo senza TreeViewItem] (http://stackoverflow.com/questions/9761336/whats-the-wpf-way-to-mark-a-command-as- disponibile solo-se-la-genitore-di-un-albero)? –