Добавление значка в TreeViewItem

Меня попросили обновить TreeVeiw в приложении WPF, которое создается на лету из объекта класса. Как вы увидите, treeveiw ни к чему не привязан. Ниже не мой код!!

<TreeView Grid.Row="0" HorizontalAlignment="Stretch" Name="tvLocations" VerticalAlignment="Stretch" SelectedItemChanged="tvLocations_SelectedItemChanged" />

    private void BuildTreeVeiw(Location locationList)
    {
        this.Title = _selectedLoc.Name +  " - Locations";
        tvLocations.Items.Clear();

        TreeViewItem tvitem;

        tvitem = new TreeViewItem() { Header = locationList.Name, Uid = locationList.Id.ToString() };

        if (locationList.Printers != null)
        {
            TreeViewItem tvprnitem = new TreeViewItem() { Header = "Printers" };
            tvprnitem.FontWeight = FontWeights.Regular;

            foreach (Printer sprinters in locationList.Printers)
            {
                TreeViewItem psubitem = new TreeViewItem() { Header = sprinters.Name, Uid = sprinters.Id.ToString() };
                TreeViewItem psubitem1 = new TreeViewItem() { Header = String.Concat("UNC: ", sprinters.UNC) };
                psubitem.Items.Add(psubitem1);
                tvprnitem.Items.Add(psubitem);
            }
            tvitem.Items.Add(tvprnitem);
        }

        foreach (Location loc in locationList.Children)
        {
            AddChildren(loc, ref tvitem);
        }
        tvLocations.Items.Add(tvitem);
    }

    private void AddChildren(Location child, ref TreeViewItem tvi)
    {
        TreeViewItem tvitem;

        tvitem = new TreeViewItem() { Header = child.Name, Uid = child.Id.ToString() };
        if (child.Name ==  _currentLocation.Name)
        {
            tvitem.FontWeight = FontWeights.Bold;
        }

        if (child.Printers != null)
        {
            TreeViewItem tvprnitem = new TreeViewItem() { Header = "Printers" };
            tvprnitem.FontWeight = FontWeights.Regular;

            foreach (Printer sprinters in child.Printers)
            {
                TreeViewItem psubitem = new TreeViewItem() { Header = sprinters.Name, Uid = sprinters.Id.ToString() };
                TreeViewItem psubitem1 = new TreeViewItem() { Header = String.Concat("UNC: ", sprinters.UNC) };
                psubitem.Items.Add(psubitem1);
                tvprnitem.Items.Add(psubitem);
            }
            tvitem.Items.Add(tvprnitem);
        }
        if (child.Children != null)
        {
            foreach (Location loc in child.Children)
            {
                AddChildren(loc, ref tvitem);
            }
        }

        tvi.Items.Add(tvitem);

    }

Это правильно строит дерево, и все, что меня попросили сделать, это добавить значок в TreeViewItem. Значок будет отличаться в зависимости от того, является ли это местоположением или принтером в этом местоположении.

Я не вижу, как добавлять значки в TreeViewItems, может ли кто-нибудь указать мне правильное направление?


person Fred    schedule 29.11.2012    source источник
comment
Почему вы не используете привязки данных? Гораздо проще работать с элементами управления WPF с привязками.   -  person Dennis    schedule 29.11.2012
comment
Да, но я надеялся, что добавление значка будет небольшим изменением. Все приложение можно было бы переписать, но время не на моей стороне.   -  person Fred    schedule 29.11.2012


Ответы (2)


Я решил это, изменив эту строку

tvitem = new TreeViewItem() { Header = child.Name, Uid = child.Id.ToString() };

To

tvitem = GetTreeView(child.Id.ToString(), child.Name, "location.png");

Добавление этой функции

    private TreeViewItem GetTreeView(string uid, string text, string imagePath)
    {
        TreeViewItem item = new TreeViewItem();
        item.Uid = uid;
        item.IsExpanded = false;

        // create stack panel
        StackPanel stack = new StackPanel();
        stack.Orientation = Orientation.Horizontal;

        // create Image
        Image image = new Image();
        image.Source = new BitmapImage
            (new Uri("pack://application:,,/Images/" + imagePath));
        image.Width = 16;
        image.Height = 16;
        // Label
        Label lbl = new Label();
        lbl.Content = text;


        // Add into stack
        stack.Children.Add(image);
        stack.Children.Add(lbl);

        // assign stack to header
        item.Header = stack;
        return item;
    }

Работал отлично.

person Fred    schedule 30.11.2012
comment
Вместо этого может быть проще использовать TextBlock, см. ветку комментариев в этом ответе. это странно, но я заметил, что TextBlock уважает цвет выбора темы для корневых узлов, но Label нет. - person jrh; 04.01.2017

Очень хорошо. Я просто добавляю этот внутренний метод, который возвращает панель стека, чтобы сделать код более читабельным:

private StackPanel CustomizeTreeViewItem(object itemObj)
{
     // Add Icon
     // Create Stack Panel
     StackPanel stkPanel = new StackPanel();
     stkPanel.Orientation = Orientation.Horizontal;

     // Create Image
     Image img = new Image();
     img.Source = new BitmapImage(new Uri("pack://application:,,/Resources/control.png"));
     img.Width = 16;
     img.Height = 16;

     // Create TextBlock
     TextBlock lbl = new TextBlock();
     lbl.Text = itemObj.ToString();

     // Add to stack
     stkPanel.Children.Add(img);
     stkPanel.Children.Add(lbl);

     return stkPanel;
}

и в TreeView Initialization

// Assign stack to header

item.Header = CustomizeTreeViewItem(itemObj);
person Ali Abdulhussein    schedule 25.02.2015