Сетка не запоминает элементы, добавляемые динамически

Я пытаюсь заполнить сетку на моей главной странице элементами веб-браузера, которые добавлены в код позади. По какой-то причине я не могу заставить сетку запомнить, какие элементы уже были добавлены. Я не знаю, как хранить эту информацию, чтобы при переходе с MainPage и обратно сетка знала, какие значения были ранее добавлены. Чтобы лучше объяснить, у меня есть следующее:

MainPage.xaml

<Grid x:Name="BrowserHost" Grid.Row="1">
    //Items will be added in code behind
</Grid>

MainPage.xaml.cs

private void ShowTab(int index) 
    {
        this.currentIndex = index;
        int count = Settings.BrowserList.Value.Count;

        if (count <= 0)
        {                
            MessageBox.Show("count <= 0");
        }
        if (currentIndex <= (count - 1))  //in correct range
        {
            // BrowserHost does not remember previously added children elements added previously when navigated back to this page and performing this check
            if(!BrowserHost.Children.Contains(Settings.BrowserList.Value[currentIndex].Browser))
                //Attempt to add browser if it was already added previously throws InvalidOperationException
                BrowserHost.Children.Add(Settings.BrowserList.Value[currentIndex].Browser);
        }

        if (currentIndex > (count - 1))
        {
            MessageBox.Show("currentIndex > (count - 1)");
        }

        for (int i = 0; i < Settings.BrowserList.Value.Count; i++)
        {
            if (Settings.BrowserList.Value.ElementAt(i) != null)
            {
                Settings.BrowserList.Value.ElementAt(i).Browser.Visibility = i == this.currentIndex ? Visibility.Visible : Visibility.Collapsed;
            }
        }
    }

По сути, метод ShowTab вызывается с определенным значением индекса каждый раз при загрузке MainPage. Выполняется проверка, существует ли Settings.BrowserList.Value[currentIndex].Browser (коллекция с экземплярами веб-браузера) в текущем индексе в списке (они добавляются на другой странице). Если сетка BrowserHost на MainPage уже содержит дочерний элемент (браузер) с определенным индексом, тогда она должна пропустить проверку и продолжать показывать этот экземпляр браузера на экране. Предполагается, что это в основном реализует сценарий просмотра с вкладками для пользовательского элемента управления веб-браузером, который я создал. Моя проблема в том, что я могу последовательно добавлять новые браузеры в BrowserHost и показывать их на экране, но когда я пытаюсь вызвать ранее добавленный веб-браузер по определенному индексу в моей коллекции, я получаю InvalidOperationException. Как мне это исправить? Моя отладка показывает, что в ShowTab, когда я проверяю, был ли добавлен браузер, независимо от того, добавлен он или нет, он пытается добавить этот браузер в дочерний элемент BrowserHost. Если браузер был создан ранее, возникает InvalidOperationException.


person Matthew    schedule 23.09.2012    source источник
comment
Я провел быстрый тест с более наивным случаем, и кажется, что в способе реализации Grid нет ничего плохого — он работал, как и ожидалось. Содержит() вернул ожидаемое значение. Перед строкой if(Contains) добавьте следующее и сообщите нам результат (остановите отладку и проверьте exists): var exists = BrowserHost.Children.FirstOrDefault(x => x == Settings.BrowserList.Value[currentIndex].Browser);   -  person Shahar Prish    schedule 24.09.2012
comment
exists имеет значение null до добавления элемента в BrowserHost, а также значение null после добавления элемента в BrowserHost. Это также равно нулю, когда я покидаю MainPage, а затем возвращаюсь и пытаюсь показать тот же элемент индекса BrowserList. Однако я добавляю новые элементы в BrowserList на другой странице. Я считаю, что выход из MainPage приводит к тому, что Grid не запоминает добавленные элементы. Однако необходимо, чтобы сетка запоминала элементы, потому что, если мой пользователь выходит из приложения, а затем возвращается, он должен иметь возможность вызывать ранее добавленные элементы браузера.   -  person Matthew    schedule 24.09.2012
comment
Оооооо. Таким образом, эти элементы могут быть родителями разных страниц?   -  person Shahar Prish    schedule 25.09.2012
comment
Ну, по сути, я пытаюсь создать вкладки на одной странице, и когда пользователь щелкает вкладку, он показывает соответствующий элемент BrowserList на главной странице. Дело в том, что на TabsPage есть список, который также заполняется элементами BrowserList, поэтому пользователь может коснуться выбранного элемента и отобразить соответствующий элемент на главной странице.   -  person Matthew    schedule 25.09.2012


Ответы (1)


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

var browser = Settings.BrowserList.Value[currentIndex].Browser;
if(!BrowserHost.Children.Contains(browser))
{

  var grid = (Grid)browser.Parent;
  if (grid != null)
  {
    grid.Children.Remove(browser);
  }
  BrowserHost.Children.Add(browser);
}

Вам также необходимо убедиться, что Браузер размещен в сетке в другой вашей форме (если он не находится непосредственно внутри сетки, просто оберните его в нее).

Это может сработать, но я настоятельно предлагаю вам найти другой способ сделать это.

person Shahar Prish    schedule 24.09.2012
comment
Это сработало для отображения существующего экземпляра браузера на экране, хотя все данные истории и еще много чего удаляются. Я собираюсь пойти дальше и принять ваш ответ, потому что это рабочее решение, и я действительно ценю помощь. Я постараюсь опубликовать, если найду другое решение. - person Matthew; 25.09.2012