Как запретить строку NewItemPlaceholder в ComboBox, привязанную к той же DataTable, что и DataGrid в WPF - PullRequest
4 голосов
/ 31 января 2012

Я - приложение в стиле мастера, которое использует страницы, и пользователь может перемещаться между ними либо с помощью кнопок «Далее» и «Предыдущий», либо с помощью навигационной панели для прямого доступа к определенным страницам.

На одной странице (я назову это «страница сетки») у меня есть DataGrid, привязанный к DataTable. В DataTable есть некоторые исходные данные, но с помощью DataGrid пользователь может добавлять, редактировать и удалять строки по своему усмотрению. На следующей странице (я назову это «страницей со списком») есть ComboBox, который привязан к той же DataTable, что и DataGrid на странице сетки. Обе страницы используют один и тот же объект в качестве контекста данных.

Если я сразу перехожу на страницу поля со списком, все работает нормально, поле со списком имеет запись для каждой строки в DataTable, как и должно быть. Теперь я перехожу на страницу сетки и ничего там не трогаю, а затем снова захожу на страницу со списком. Теперь ComboBox отображает новый элемент, NewItemPlaceholder. Очевидно, это происходит потому, что в DataGrid для UserCanAddRows установлено значение true, и, таким образом, отображается строка-заполнитель для нового элемента. Но это должно касаться только DataGrid, а не связанной DataTable, так что, на мой взгляд, это ошибка или, по крайней мере, абсолютно ужасный дизайн.

Конечно, я не хочу, чтобы NewItemPlaceholder в моем ComboBox (и выбор его вызывает много проблем). Итак, как я могу предотвратить его отображение в ComboBox?

Обновление: тем временем я обнаружил, что элемент-заполнитель не находится в DataTable как строка, что делает его еще более странным, если в DataTable нет флага, который говорит: «В этой таблице есть NewItemPlaceholder», но не сам ряд Кроме того, когда я регистрируюсь в событии Initialized ComboBox, у меня есть 2 элемента, которые я ищу, когда я регистрируюсь в событии Loaded, у меня также есть NewItemPlaceholder, поэтому он должен быть добавлен где-то между этими двумя событиями.

Ответы [ 2 ]

3 голосов
/ 20 ноября 2015

Использовать CollectionViewSource.Проблема возникает, когда несколько элементов управления совместно используют одно и то же представление коллекции, например когда коллекция связана в одном случае с DataGrid, а в другом - с ComboBox.Если DataGrid позволяет пользователю добавлять элементы (т. Е. CanUserAddRows объекта DataGrid имеет значение true), то в представление может быть добавлен держатель NewItemPlace.Попробуйте что-то вроде

<UserControl >
<UserControl.Resources >
    <CollectionViewSource Source="{Binding MyCollection}"
             x:Key="SourceWithoutNewItemPlaceholder" />
</UserControl.Resources>

  <Grid Name="LayoutGrid" >

   <ComboBox ItemsSource={Binding Source={StaticResource SourceWithoutNewItemPlaceholder}} >

  </Grid>
</UserControl>
0 голосов
/ 01 февраля 2012

После нескольких неудачных попыток я нашел 2 решения:

1) В событии Loaded страницы я делаю привязку в коде не к самой DataTable, а к DataTable.ToList.Если я сделаю это таким образом, держатель NewItemPlace не будет отображаться.

2) В модели представления я создаю новое свойство, которое возвращает DataTable.ToList и связывается с ним.Таким образом, я могу выполнить привязку в XAML.

Только для справки, методы, которые не работают: свойство Filter в ComboBox создает исключение NotSupportedException, кажется, DataTable не поддерживает это.Удаление NewItemPlaceholder в событии Loaded ComboBox также не работает, потому что вы не можете удалять элементы, когда установлен ItemsSource.Удаление NewPlaceHolderItem при выходе из страницы с сеткой данных также не работает, потому что я не могу найти, где она находится (ее нет в DataTable или в представлении DataTable)

...