Vraag Programmatisch een item selecteren in een WPF TreeView?


Hoe is het mogelijk om een ​​item in een WPF programmatisch te selecteren TreeView? De ItemsControl model lijkt het te voorkomen.


39
2018-01-05 17:38


oorsprong


antwoorden:


Het is om een ​​of andere vreemde reden een echte pijn, je moet ContainerFromItem gebruiken om de container te krijgen en vervolgens de selectiemethode aanroepen.

//  selectedItemObject is not a TreeViewItem, but an item from the collection that 
//  populated the TreeView.

var tvi = treeView.ItemContainerGenerator.ContainerFromItem(selectedItemObject) 
          as TreeViewItem;

if (tvi != null)
{
    tvi.IsSelected = true;
}

Er was ooit een blogbericht over hoe het te doen hier, maar de link is nu dood.


16
2018-01-05 17:44



Voor degenen die nog steeds op zoek zijn naar de juiste oplossing voor dit probleem, is dit hieronder. Ik vond deze in het commentaar op het artikel over het codeproject "WPF TreeView Selection" http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx door snapchatanderer. Het werd gepost door Kenrae op 25 november 2008. Dit werkte prima voor mij. Bedankt Kenrae!

Hier is zijn bericht:

In plaats van de tree te lopen, moet u uw eigen data-object de eigenschap IsSelected hebben (en ik raad ook de eigenschap IsExpanded aan). Definieer een stijl voor de TreeViewItems van de structuur met behulp van de eigenschap ItemContainerStyle in de TreeView die die eigenschappen uit het TreeViewItem aan uw gegevensobjecten koppelt. Iets zoals dit:

<Style x:Key="LibraryTreeViewItemStyle"
               TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded"
                        Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected"
                        Value="{Binding IsSelected, Mode=TwoWay}" />
            <Setter Property="FontWeight"
                        Value="Normal" />
            <Style.Triggers>
                  <Trigger Property="IsSelected"
                              Value="True">
                        <Setter Property="FontWeight"
                                    Value="Bold" />
                  </Trigger>
            </Style.Triggers>
      </Style>

<TreeView ItemsSource="{Binding Path=YourCollection}"
               ItemContainerStyle="{StaticResource LibraryTreeViewItemStyle}"
               ItemTemplate={StaticResource YourHierarchicalDataTemplate}/>

36
2017-11-02 17:46



Je moet de TreeViewItem en stel dan in IsSelected naar true.


22
2018-01-05 17:44



Dit is niet zo eenvoudig als het lijkt, de link van Steven heeft een oplossing uit 2008, die misschien nog steeds werkt, maar niet zorgt voor gevirtualiseerde TreeViews. Bovendien worden veel andere problemen genoemd in de opmerkingen van dat artikel. Geen vergrijpen, maar ik zit ook vast met hetzelfde probleem en kan geen perfecte oplossing vinden. Hier zijn de links naar enkele artikelen / berichten die me veel hebben geholpen-

Hoe kan ik items uitbreiden in een TreeView? - Deel III: http://bea.stollnitz.com/blog/?p=59

Programmatisch Een item in een structuur selecterenBekijk: http://blog.quantumbitdesigns.com/2008/07/22/programmatically-selecting-an-item-in-a-treeview/#respond

TreeView, TreeViewItem en IsSelected: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7e368b93-f509-4cd6-88e7-561e8d3246ae/


5
2017-08-09 09:15



Ik ben geslaagd met deze code:

public static TreeViewItem FindTviFromObjectRecursive(ItemsControl ic, object o) {
  //Search for the object model in first level children (recursively)
  TreeViewItem tvi = ic.ItemContainerGenerator.ContainerFromItem(o) as TreeViewItem;
  if (tvi != null) return tvi;
  //Loop through user object models
  foreach (object i in ic.Items) {
    //Get the TreeViewItem associated with the iterated object model
    TreeViewItem tvi2 = ic.ItemContainerGenerator.ContainerFromItem(i) as TreeViewItem;
    tvi = FindTviFromObjectRecursive(tvi2, o);
    if (tvi != null) return tvi;
  }
  return null;
}

Gebruik:

var tvi = FindTviFromObjectRecursive(TheTreeView, TheModel);
if (tvi != null) tvi.IsSelected = true;

2
2017-09-17 10:51



Ik schreef een uitbreidingsmethode:

using System.Windows.Controls;

namespace Extensions
{
    public static class TreeViewEx
    {
        /// <summary>
        /// Select specified item in a TreeView
        /// </summary>
        public static void SelectItem(this TreeView treeView, object item)
        {
            var tvItem = treeView.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
            if (tvItem != null)
            {
                tvItem.IsSelected = true;
            }
        }
    }
}

Wat ik zo kan gebruiken:

if (_items.Count > 0)
    _treeView.SelectItem(_items[0]);

2
2018-03-07 22:09



Probeer dit eens

    /// <summary>
    /// Selects the tree view item.
    /// </summary>
    /// <param name="Collection">The collection.</param>
    /// <param name="Value">The value.</param>
    /// <returns></returns>
    private TreeViewItem SelectTreeViewItem(ItemCollection Collection, String Value)
    {
        if (Collection == null) return null;
        foreach(TreeViewItem Item in Collection)
        {
            /// Find in current
            if (Item.Header.Equals(Value))
            {
                Item.IsSelected = true;
                return Item;
            }
            /// Find in Childs
            if (Item.Items != null)
            {
                TreeViewItem childItem = this.SelectTreeViewItem(Item.Items, Value);
                if (childItem != null)
                {
                    Item.IsExpanded = true;
                    return childItem;
                }
            }
        }
        return null;
    }

Referentie: http://amastaneh.blogspot.com/2011/06/wpf-selectedvalue-for-treeview.html


0
2018-06-01 16:50



Ik dacht dat ik zou ingaan op de oplossing waar ik mee ging, voor het geval dit iedereen kan helpen. Merk op dat de beste manier om dit te doen is het gebruik van een bound-eigenschap zoals 'IsSelected' als antwoord van kuninl, maar in mijn geval was het een oudere applicatie die MVVM niet volgde, dus ik eindigde met de onderstaande.

private void ChangeSessionSelection()
{
    foreach (SessionContainer item in this.treeActiveSessions.Items)
    {
        var treeviewItem = this.treeActiveSessions.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;

        if (item.Session == this.selectedSession.Session)
        {
            treeviewItem.IsSelected = true;
            treeviewItem.IsExpanded = true;
        }
        else
        {
            treeviewItem.IsSelected = false;
            treeviewItem.IsExpanded = false;
        }
    }            
}

Wat dit doet, is het selecteren en uitbreiden van het treeview-item in de gebruikersinterface die het geselecteerde gegevensitem in de code erachter vertegenwoordigt. Het doel hiervan was om de selectie te laten wijzigen in de boomstructuur wanneer de gebruikersselectie in een itembeheer in hetzelfde venster werd gewijzigd.


0
2018-01-08 13:55



Als u een item wilt selecteren dat zich binnen kinderen van een kind bevindt, kunt u recursie door de gebruiker doen.

public bool Select(TreeViewItem item, object select) // recursive function to set item selection in treeview
{
    if (item == null)
        return false;
    TreeViewItem child = item.ItemContainerGenerator.ContainerFromItem(select) as TreeViewItem;
    if (child != null)
    {
        child.IsSelected = true;
        return true;
    }
    foreach (object c in item.Items)
    {
        bool result = Select(item.ItemContainerGenerator.ContainerFromItem(c) as TreeViewItem, select);
        if (result == true)
            return true;
    }
    return false;
}

0
2017-09-06 12:19



Ik heb een methode gemaakt VisualTreeExt.GetDescendants<T>die een opsomming geeft van een verzameling elementen die overeenkomen met het opgegeven type:

public static class VisualTreeExt
{
  public static IEnumerable<T> GetDescendants<T>(DependencyObject parent) where T : DependencyObject
  {
    var count = VisualTreeHelper.GetChildrenCount(parent);
    for (var i = 0; i < count; ++i)
    {
       // Obtain the child
       var child = VisualTreeHelper.GetChild(parent, i);
       if (child is T)
         yield return (T)child;

       // Return all the descendant children
       foreach (var subItem in GetDescendants<T>(child))
         yield return subItem;
    }
  }
}

Wanneer je erom vraagt VisualTreeHelperExt.GetDescendants<TreeViewItem>(MyAmazingTreeView) je krijgt alle TreeViewItem Childs. U kunt een bepaalde waarde selecteren met behulp van het volgende stuk code:

var treeViewItem = VisualTreeExt.GetDescendants<TreeViewItem>(MyTreeView).FirstOrDefault(tvi => tvi.DataContext == newValue);
if (treeViewItem != null)
  treeViewItem.IsSelected = true;

Het is een beetje een vuile oplossing (en waarschijnlijk niet de meest efficiënte) en zal niet werken als je een gevirtualiseerde TreeView gebruikt, omdat dit afhangt van het bestaan ​​van de visuele elementen zelf. Maar het werkt voor mijn situatie ...


0
2017-08-14 14:34