Как сделать прозрачный combobox wpf

Добавил пользователь Дмитрий К.
Обновлено: 04.10.2024

у меня есть ComboBox, который, кажется, не обновляет SelectedItem/SelectedValue.

элемент ComboBox ItemsSource привязан к свойству в классе ViewModel, который перечисляет кучу записей телефонной книги RAS как CollectionView. Тогда я связал (в разное время) оба SelectedItem или SelectedValue к другому свойству ViewModel. Я добавил MessageBox в команду save для отладки значений, установленных привязкой данных, но SelectedItem / SelectedValue привязка не быть набор.

класс ViewModel выглядит примерно так:

коллекция _phonebookEntries инициализируется в конструкторе из бизнес-объекта. XAML ComboBox выглядит примерно так:

меня интересует только фактическое строковое значение, отображаемое в выпадающем списке, а не любые другие свойства объекта, поскольку это значение мне нужно передать в RAS, когда я хочу сделать VPN-соединение, следовательно DisplayMemberPath и SelectedValuePath оба свойства имени ConnectionViewModel. ComboBox находится в DataTemplate применил к ItemsControl в окне кто DataContext был установлен в экземпляр ViewModel.

что мне не хватает с привязкой данных ComboBox? Я много искал и не могу найти ничего, что я делаю неправильно.

это поведение, которое я вижу, однако оно не работает по какой-то причине в моем конкретном контексте.

у меня есть MainWindowViewModel, который имеет CollectionView из ConnectionViewModels. В MainWindowView.код файла xaml, я установил DataContext в значение MainWindowViewModel. В MainWindowView.xaml имеет ItemsControl привязан к коллекции ConnectionViewModels. У меня есть DataTemplate, который содержит ComboBox, а также некоторые другие текстовые поля. Текстовые поля привязаны непосредственно к свойствам ConnectionViewModel с помощью Text="" .

тогда XAML:

текстовые поля все связываются правильно, и данные перемещаются между ними и ViewModel без труда. Это только комбобокс, который не работает.

вы правы в своем предположении относительно класса PhonebookEntry.

предположение, которое я делаю, заключается в том, что DataContext, используемый моим DataTemplate, автоматически устанавливается через иерархию привязки, так что мне не нужно явно устанавливать его для каждого элемента в ItemsControl . Мне это кажется немного глупым.

вот тестовая реализация, которая демонстрирует проблему, на основе приведенного выше примера.

XAML:

The код:

если вы запустите этот пример, вы получите поведение, о котором я говорю. Текстовое поле обновляет свою привязку штраф при редактировании его, но ComboBox не делает. Очень запутанный видя, как на самом деле единственное, что я сделал, это ввести Родительский ViewModel.

в настоящее время я работаю под впечатлением, что элемент привязан к ребенок с DataContext, что ребенок, как значение DataContext. Я не могу найти никакой документации, которая проясняет это так или иначе.

Window - > DataContext = MainWindowViewModel
..Элементы - > привязка к DataContext.PhonebookEntries
. Item - > DataContext = PhonebookEntry (неявно связанный)

я не знаю, если это объясняет мое предположение лучше(?).

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

и это покажет корень привязки TextBox (который я сравниваю с DataContext) является экземпляром ConnectionViewModel.

23 ответа

Я сделал это, прежде чем связывать комбобокс с данными из базы данных в codebehind вроде этого -

Это просто добавляет текст в качестве опции в раскрывающемся списке. Это не то, о чем просил ОП. – Dean Friedland 2 July 2018 в 16:58

речь идет о добавлении текста по умолчанию, и я сделал это таким образом – bax 1188 3 July 2018 в 08:19

Самый простой способ, который я нашел для этого, это:

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

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

Очень простой и лучший вариант в приложении MVVM, которое я создал. Большое спасибо – user 10 April 2013 в 14:49

идеальный ответ Крис. Одно свойство может иметь такую ​​большую разницу: D – Aster Veigas 8 September 2013 в 22:14

Простое и эффективное решение. Элементы управления WPF имеют такие проблемы во всей структуре. Здесь и там элементы управления не имеют функций, которые потребуются большинству разработчиков. В результате разработчики тратят время на поиск решений, покупку сторонних альтернативных элементов управления или реализацию обходных решений . Разве команда WPF даже использует свои средства управления для своих собственных разработок? – Damn Vegetables 10 January 2015 в 19:27

. Требуется немного кода, но вы можете повторно использовать его для любого combobox или текстового поля (и даже пароли), поэтому я предпочитаю этот путь

Ницца. Я расширил его, привязываясь к TextBlock DataContext, используя относительный источник, чтобы избежать необходимости устанавливать имя. См. Следующий комментарий для Markup (код в комментариях SO выглядит уродливым) – Sascha 14 October 2016 в 10:18

Мне нравится ответ Tri Q, но эти преобразователи ценности - боль в использовании. PaulB сделал это с обработчиком событий, но это тоже не нужно. Вот чистое решение XAML:

Немного поздно, но ..

Более простым способом было бы добавить фиктивный элемент данных в список с параметром IsDummy = true и убедиться, что он не является HitTestVisable, а его высота равна 1 пикселю ( используя конвертер), поэтому его не видно.

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

Он работает как шарм и этот способ вы не испортите стиль и цвета ComboBox или темы вашего приложения.

Никто не сказал, что чистое решение xaml должно быть сложным. Вот простой, с 1 триггером данных в текстовом поле. Маржа и позиция по желанию

Мне нужно было переместить & quot; Видимость = & quot; Скрытый & quot; в триггер данных. то он работал, как ожидалось. Определенно, самый прямой подход, который я видел. Для повторного использования я переместил стиль в ресурс – Mitch 9 August 2013 в 15:50

Ответ @Mitch IceForce не работает для меня, что вы изменили, чтобы заставить его работать? – Chris 30 April 2014 в 11:20

@Chris Я думаю, что он имел в виду добавление за курок (внутри стиля) и удаление Visibility="Hidden" из фактического элемента текстового блока – BroSlow 23 May 2015 в 01:39

Приведенный выше код демонстрирует самый простой способ его достижения. После загрузки окна объявите текст комбобокса, используя свойство .Text в поле со списком. Это также можно расширить до DatePicker, Textbox и других элементов управления.

Не лучшая практика . но отлично работает .

Установите IsEditable = True в элементе Combobox. Это отобразит свойство Text для Combobox

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

Он использует слой adorner здесь для отображения водяного знака.

Просто скачал и пробовал этот код. Кажется, он работает как рекламируемый. Позволяет вам украсить вашу комбо простым прикрепленным свойством, содержащим ваш водяной знак. Он также работает и для других элементов управления. Это гораздо лучший подход, чем любой другой ответ на этот вопрос. – Ian Oakes 26 August 2011 в 11:20

Хороший материал, и не только он решает проблему ComboBox, но теперь я могу избавиться от сборки WPF Tools и просто использовать это в своих текстовых блоках, а не в контроле WatermarkedTextBox, так что полный выигрыш :) - о, btw, это A Geek Trapped not Согласованная ловушка! – dain 5 January 2012 в 15:19

Решение HappyNomad было очень хорошим и помогло мне в конечном итоге прийти к этому немного другому решению.

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

Затем в выбранном измененном обработчике .

Вместо создания обработчика SelectionChanged видимость TextBlock может быть установлена ​​в XAML. – aliceraunsbaek 16 July 2013 в 13:40

РЕДАКТИРОВАТЬ: По комментариям ниже, это не решение. Не знаю, как я работал, и не могу проверить этот проект.

Пришло время обновить этот ответ для последнего XAML.

Находя этот вопрос SO, ища решение этого вопроса, я обнаружил, что обновленная спецификация XAML имеет простое решение.

Я использовал это решение - помогает ли негативная избирательная система? Конечно, я не эксперт XAML, но он сработал. – Robb Sadler 26 October 2017 в 17:30

Человек это странно - я знаю, что я работал над XAML-приложением, и я знаю, что только что открыл его и увидел, что он работает. Может быть, расширение было включено в проект? IDK. С тех пор я посмотрел и наверняка нет Placeholder в ComboBox. Я не могу вернуться к проекту, над которым работал старый клиент. тьфу. – Robb Sadler 29 March 2018 в 13:47

add пространство имен в файле xaml.

использует эту строку под ресурсами, чтобы сделать ее доступной через код xaml

здесь - код xaml, я использовал здесь триггер, поэтому всякий раз, когда элемент выбирается в поле со списком, видимость вашего текста становится ложной.

Вы можете сделать это без какого-либо кода с помощью IValueConverter .

Здесь вы можете выбрать класс конвертера, который вы можете повторно использовать.

И, наконец, вам нужно объявить ваш конвертер в разделе ресурсов.

Где конвертеры - это место, где вы разместили класс конвертера. Например:

Очень приятная вещь в этом подходе - это не повторение кода в коде.

Я хотел бы использовать это, но кажется, что это запрещено в случаях, когда combobox является заголовком datagrid. , , XAML дает ошибку, что заголовок уже определен (или, возможно, не может быть определен более одного раза). Есть идеи? Я думаю просто использовать параметр с нулевым значением, который затем позволит сбросить его, выбирая его, но кажется немного неряшливым. – Paul Gibson 29 January 2015 в 20:57

Большая причина, по которой это отличное решение, состоит в том, что почти каждый связанный с данными проект WPF использует NullToVisibilityConverter, так что он уже там в большинстве случаев - может также использовать его! – tpartee 16 June 2015 в 00:36

На самом деле вы можете использовать DataTrigger , чтобы избежать даже кода конвертера здесь :) – Billy ONeal 2 September 2015 в 18:17

Я знаю, что это полу-старое, но как насчет этого пути:

Я бы рекомендовал следующее:

Спасибо за указание на это. Я не смог выполнить эту ошибку на своем компьютере. Однако я согласен, что typeof (ComboBoxBehaviors) должен быть передан в третьем параметре RegisterAttached вместо typeof (ComboBox). – Usman Zafar 9 June 2014 в 17:50

Как изменить цвет фона Combobox при щелчке (открыт ComboBox) в WPF?

3 ответа

Вот немного наивный подход:

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

  1. В некоторых темах Windows (например, тема Aero, используемая в Vista и Windows 7), зеленый фон скрывается голубоватым цветом, который используется темой, чтобы указать, что кнопка раскрывающегося меню была нажата. Таким образом, кнопка ненадолго загорится зеленым цветом, прежде чем исчезнет с Cyan.
  2. ComboBox.Background Свойство влияет только на внешний вид самой кнопки, а не на выпадающий список. Возможно, что вы действительно хотите изменить цвет фона всплывающей части.

Если 2 - это то, что вы хотели, это поможет:

Строго говоря, это на самом деле меняет цвет фона ComboBoxItem элементы управления, которые появляются в раскрывающемся списке, но будут иметь желаемый эффект.

Я разрабатываю приложение, используя подход WPF mvvm. У меня есть требование, когда я должен показать список элементов в поле со списком для выбора. На основе некоторого флага мне нужно отфильтровать несколько элементов из поля со списком для выбора.

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

Существует много разных способов сделать это, но мое личное предпочтение – использовать ListCollectionView в качестве ListCollectionView элемента управления, отображающего отфильтрованный список, установить предикат фильтра в ListCollectionView.Filter и вызвать ListCollectionView.Refresh когда параметры фильтра изменяются.

Пример ниже будет фильтровать список стран, основанных на их континенте.

Есть ли простой способ применения фильтров в существующем списке на основе некоторого флага?

Хотя ваш вопрос непонятен, но я думаю, вам не нужно поддерживать два списка, чтобы получить данные фильтра. Вы можете использовать простой LINQ для фильтрации. Предположим, что у вас есть свойство ViewModel, например

И вы хотите отфильтровать это на основе некоторых значений bool, тогда вы можете написать что-то вроде

Статус может быть bool на основе того, что вы хотите отфильтровать свои данные, и вы можете добавить этот bool в свой класс ComboBoxItem.

Читайте также: