Связывание WPF Combobox: невозможно изменить выбор - PullRequest
3 голосов
/ 03 июня 2010

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

У меня есть три поля со списком и текстовое поле в форме WPF, и у меня есть Subsonic 3 ActiveRecord DAL. Когда я загружаю эту форму «Редактировать запись», поля со списком заполняются правильно, они выбирают правильные элементы, и текстовое поле имеет правильный текст. Я могу изменить текст TextBox и сохранить запись просто отлично, но комбинированные списки НЕ МОГУТ БЫТЬ ИЗМЕНЕНЫ. Списки раскрываются и выделяются, но при нажатии на элемент выбранный элемент остается прежним.

Вот мой XAML:

<StackPanel Orientation="Horizontal" Margin="10,10,0,0">
    <TextBlock Width="80">Asset</TextBlock>
    <ComboBox Name="cboAsset" Width="180"  
      DisplayMemberPath="AssetName"
      SelectedValuePath="AssetID" 
      SelectedValue="{Binding AssetID}" ></ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10,10,0,0">
    <TextBlock Width="80">Status</TextBlock>
    <ComboBox Name="cboStatus" Width="180" 
      DisplayMemberPath="JobStatusDesc"  SelectedValuePath="JobStatusID"  
      SelectedValue="{Binding JobStatusID}" ></ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10,10,0,0">
    <TextBlock Width="80">Category</TextBlock>
    <ComboBox Name="cboCategories" Width="180" 
      DisplayMemberPath="CategoryName"
      SelectedValuePath="JobCategoryID"
      SelectedValue="{Binding JobCategoryID}" ></ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10,10,0,0">
    <TextBlock Width="80">Reason</TextBlock>
    <TextBox Name="txtReason" Width="380" Text="{Binding Reason}"/>
</StackPanel>

Вот соответствующие фрагменты моего кода (передается intJobID):

SvcMgrDAL.Job oJob;
IQueryable<SvcMgrDAL.JobCategory> oCategories = SvcMgrDAL.JobCategory.All().OrderBy(x => x.CategoryName);
IQueryable<SvcMgrDAL.Asset> oAssets = SvcMgrDAL.Asset.All().OrderBy(x => x.AssetName);
IQueryable<SvcMgrDAL.JobStatus> oStatus = SvcMgrDAL.JobStatus.All();

    cboCategories.ItemsSource = oCategories;
    cboStatus.ItemsSource = oStatus;
    cboAsset.ItemsSource = oAssets;
    this.JobID = intJobID;
    oJob = SvcMgrDAL.Job.SingleOrDefault(x => x.JobID == intJobID);
    this.DataContext = oJob;

Вещи, которые я пробовал:

  • Явно устанавливает IsReadOnly="false" и IsSynchronizedWithCurrentItem="True"
  • Изменение поля со списком ItemSources с IQueryables на Lists.
  • Создание собственного объекта Job (простой класс сущностей vanilla, использующий INotifyPropertyChanged).
  • Каждый режим привязки для выпадающих списков.
  • ItemsSource="{Binding}"

Subsonic DAL не реализует INotifyPropertyChanged, но я не вижу необходимости в таком простом связывании, как это. Я просто хочу иметь возможность выбрать что-то из выпадающего списка и сохранить его.

Сравнивая это с моей последней проблемой (ссылка в верхней части этого сообщения), я, кажется, что-то действительно странное происходит с источниками данных. Может быть, это дозвуковая вещь?

РЕДАКТИРОВАТЬ: По какой-то причине установленный метод доступа применяется только к свойству AssetID и только в первый раз. WPF сейчас движется к WTF:)

РЕДАКТИРОВАТЬ 2: Ты, должно быть, шутишь - я удалил привязку (т. Е. У нее есть только displaymemberpath, valuememberpath и itemssouce), и это ВСЕ ЕЩЕ делает это! Он принимает ваш первый выбор, а затем не изменится.

Ответы [ 6 ]

4 голосов
/ 31 декабря 2011

Комбинированные поля WPF не изменят выбранный элемент, если текущий выбранный элемент и только что выбранный элемент считаются равными с помощью метода object.Equals(), вызываемого для вновь выбранного объекта (т.е. newlyslected.Equals(previoslySelected)).

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

1 голос
/ 01 февраля 2013

Старая тема, но у меня была та же проблема и проблема с поиском решения. Это может помочь кому-то еще. Подсказка выше в WPF не обнаруживает, что пользователь выбрал другой элемент. (Симптом - событие ComboBox_SelectionChanged срабатывает только при первом выборе)

Мой сценарий - комбо поиска, заполненный из IList, созданный из запроса DISTINCT. В этом случае результат использования NHibernate ICriteria.SetResultTransformer, который возвращает только НЕКОТОРЫЕ поля, важно НЕ включая уникальный идентификатор объекта.

Решение - перебрать IList после поиска и дать каждому объекту уникальный идентификатор. WPF видит их как личностей и ведет себя соответственно.

Это только поиск значений - это контент значений, за которым я следовал.

«Временные» сущности никогда не сохраняются. В этом случае это был лучший подход, чем возиться с переопределением метода Equals объекта ради простой проблемы с графическим интерфейсом. Альтернативой может быть просто скопировать или преобразовать список в формат, в котором WPF использует поле значения для определения «разницы» ...

1 голос
/ 03 июня 2010

Я сузил его до объектов Subsonic, используемых в качестве ComboBoxItems.Если вы создаете новый класс, который использует точно такой же код, что и соответствующие части Subsonic, он работает.Если вы используете POCO / datatables для комбо и Subsonic для редактируемой записи, это работает.Но если вы используете Subsonic для обоих, это не так.

Я надеялся расширить дозвуковые объекты и не должен кодировать полноценный уровень BLL.Похоже, я сталкиваюсь с этим или выбрасываю Subsonic для DAL.Я мог бы опубликовать более конкретный вопрос для дозвуковых людей.

Большое спасибо всем, кто внес свой вклад.

0 голосов
/ 03 июня 2010

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

Планируете ли вы какие-либо события? Если ваш код подключается к событию типа PreviewMouseLeftButtonUp и помечает событие как обработанное, то, вероятно, комбобокс может игнорировать и ничего не выбирать.

0 голосов
/ 03 июня 2010

Трудно отличить небольшой пример кода, но попробуйте закомментировать строку:

//this.DataContext = oJob; 

и посмотрите, поможет ли это.

Установка DataContext и ItemsSource может вызывать конфликт.

0 голосов
/ 03 июня 2010

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

Я не знаю этот DAL, но можете ли вы пройти через код установщика свойств? У вас также может быть проблема с преобразованием типов.

РЕДАКТИРОВАТЬ чтение вашего комментария о красном прямоугольнике - звучит так, как будто ваша собственность (или что-то связанное с привязкой) вызывает исключение. Если, конечно, вы не используете проверку данных в вашем пользовательском интерфейсе. Вы можете включить «Разбить все исключения» в настройках отладчика, если вы используете Visual Studio.

РЕДАКТИРОВАТЬ 2 Необходимо проверить панель вывода VS на наличие сообщений об ошибках, связанных с привязкой. Вы также можете прочитать это сообщение в блоге , в котором содержится дополнительная информация об отладочных привязках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...