Удаление элемента вкладки на основе его заголовка


Прежде всего, этот вопрос является продолжением этого вопроса. Я чувствую, что получил только половину ответа на свой вопрос.

А также удаление tabItems, на которое ссылается Name, я также должен иметь возможность удалять tabItems, ссылаясь на их Headers.

При реализации моего ответа и изменении n.Name на n.Header, например:

var tabToDelete = tabControl.Items.OfType<TabItem>().SingleOrDefault(n => n.Header == stringValue);
if (tabToDelete != null) 
tabControl.Items.Remove(tabToDelete);
Я нахожу, что это не работает одинаково. Должно ли это работать, или мне нужно отредактировать всю эту структуру? Если да, то как бы я это сделал, чтобы сделать уверен, что на tabItem, который мне нужен, ссылается Header?

Добавление : когда вкладки, на которые ссылается Name, удаляются, они удаляются с экрана, в то время как вкладки, на которые ссылается Header, не удаляются (до тех пор, пока вы вручную не переключите вкладки). Это наводит меня на мысль, что они все еще существуют в программе.

2 2

2 ответа:

Ваша проблема в том, что Header - это объект, а не строка. Вы сравниваете два значения, как если бы они были, но поскольку заголовок-это объект, вы фактически делаете сравнение ссылок, а не сравнение значений. Вам нужно привести Header к строке, просто вызвав .ToString() на Header.

var tabToDelete = tabControl.Items.OfType<TabItem>().SingleOrDefault(n => (n.Header as string) == stringValue);
if (tabToDelete != null)
    tabControl.Items.Remove(tabToDelete);

Если это не решает проблему, вы можете заставить элемент управления перерисовать, вызвав

tabControl.Refresh();

Обновление

Хвала Даниэлю Хименесу за обнаружение возможной нулевой ссылки исключение. Вопрос о том, что Header устанавливается в элемент управления, не является проблемой, однако, поскольку все объекты могут вызывать ToString(), реальная проблема заключается в том, что Header не устанавливается вообще, что приводит к объекту null.

Как сказал Райан, проблема в том, что Header может быть элементом управления, а не просто текстом. Если Header может быть null, as String или Convert.ToString() будет лучше, чем toString(), потому что они оба могут обрабатывать преобразование из нулевых значений, тогда как ToString() создает исключение.

Использование Convert.ToString() может быть излишним, но если ваши заголовки привязаны к значениям, которые не могут неявно преобразовываться в строки, такие как целые числа, то использование Convert.ToString() сможет их обрабатывать. Также это решение будет обрабатывать случай, если несколько элементов с таким же значением заголовка существуют.

private void RemoveTabByHeader(string str) 
{
    TabsMain.Items.OfType<TabItem>().Where(t => Convert.ToString(t.Header) == str)
       .ToList().ForEach(t => TabsMain.Items.Remove(t));
}

Это проверено. TabControl правильно обновляется.