«Элемент уже является логическим дочерним элементом другого элемента» Исключение, даже если набор элементов очищен - PullRequest
0 голосов
/ 06 августа 2020

Возникшее исключение говорит само за себя:

System.InvalidOperationException: 'Элемент уже имеет логического родителя. Он должен быть отсоединен от старого родителя, прежде чем он будет присоединен к новому. '

Однако не имеет смысла, что он создается в конце следующего метода, который является обработчик событий, который обновляет значок, отображаемый в NavigationItem (UserControl), инициированный отдельным исполняющимся потоком, который проверяет состояние соединения и запускает событие, если состояние соединения изменилось (т.е. было отключено -> теперь подключено, и наоборот).

Метод, в котором исключение выбрасывается в конце:

void OnMachineConnectionStatusChangedHandler(object source, EventArgs e)
{
    Dispatcher.Invoke(() =>
    {

        Machine machine = source as Machine;

                    // obtain the TreeViewItem representing this machine in the navigation tree

                    lock (_navigationTree)
        {
            foreach (TreeViewItem navigationItem in _navigationTree.Items)
            {

                NavigationItem machineNavItem = navigationItem.Header as NavigationItem;

                if (machineNavItem.Machine.Equals(machine))
                {
                    lock (machineNavItem)
                    {
                        machineNavItem.Refresh(); // changes shown icon

                                    if (machine.Connected)
                        {
                            if (navigationItem.Items.Count > 0)
                                navigationItem.Items.Clear(); // clear prev. items shown under

                                        TreeViewItem TO = new TreeViewItem()
                            {
                                Header = "TO",
                                Padding = new Thickness(0, 2.5, 10, 2.5)
                            };
                            TreeViewItem WO = new TreeViewItem()
                            {
                                Header = "WO",
                                Padding = new Thickness(0, 2.5, 10, 2.5)
                            };
                            TreeViewItem EWO = new TreeViewItem()
                            {
                                Header = "EWO",
                                Padding = new Thickness(0, 2.5, 10, 2.5)
                            };

                            List<int> machineHolds = machine.getActiveHoldNumbers();

                            if (machineHolds.Count > 1)
                            {
                                foreach (int hold in machineHolds)
                                {
                                    TreeViewItem holdItem = new TreeViewItem() { Header = ("#" + hold) };
                                    TO.Items.Add(hold);
                                    WO.Items.Add(hold);
                                    EWO.Items.Add(hold);
                                }

                            }

                            navigationItem.Items.Add(TO);
                            navigationItem.Items.Add(WO);
                            navigationItem.Items.Add(EWO);

                            navigationItem.IsExpanded = false;
                        }
                    }
                }
            }
        }

        this.UpdateLayout();
    }); // here, the Exception is thrown
}

Я выполнял отладку с помощью VS, проходя через каждую строку и в целом, ничего не выдает исключение, кроме как в конце.

Для справки, вот структура UserControl NavigationItem, если она имеет какое-либо отношение:

public partial class NavigationItem : UserControl
{
    // fields
    private Machine _machine;

    // properties
    public Machine Machine
    {
        get { return _machine; }
    }

    public NavigationItem(Machine machine)
    {
        InitializeComponent();

        _machine = machine;

        if (_machine.Connected)
            _statusImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Checkmark-Icon.png"));
        else
            _statusImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/X-Icon.png"));

        _machineNameLabel.Content = _machine.Name;
    }

    public void Refresh()
    {
        if (_machine.Connected)
            _statusImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Checkmark-Icon.png"));
        else
            _statusImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/X-Icon.png"));
    }
}

Любая помощь или руководство были бы очень признательны в отношении того, почему это исключение создается и устраняется.

1 Ответ

0 голосов
/ 07 августа 2020

Выяснилось после того, как закомментировал код, чтобы сузить, какая строка / раздел является виновником.

Проблема в:

foreach (int hold in machineHolds)
{
    TreeViewItem holdItem = new TreeViewItem()
    { Header = ("#" + hold) };
    TO.Items.Add(hold);
    WO.Items.Add(hold);
    EWO.Items.Add(hold);
}

Проблема в том, что я инициализирую один TreeViewItem , holdItem, но попытайтесь добавить его к 3 различным «родительским» элементам TreeViewItem. Таким образом, решение:

foreach (int hold in machineHolds)
{
    foreach (int type = 0; type < 3; type++)
    {
        TreeViewItem holdItem = new TreeViewItem()
            { Header = ("#" + hold) };
        switch (type){
            case 0:
                TO.Items.Add(hold);
                break;
            case 1:
                WO.Items.Add(hold);
                break;
            case 2:
                EWO.Items.Add(hold);
                break;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...