2010-06-03 2 views
3

После того, как вы потратили время на это, следуя по пятам моего Last Problem, я начинаю ощущать, что Framework 4 является мастером тонкого зла, или мой компьютер преследует.WPF Combobox binding: не может изменить выбор

У меня есть три comboboxes и текстовое поле в форме 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"
  • Ch обводка combobox ItemSources от IQueryables до Lists.
  • Построение моего собственного объекта работы (простой класс сущности ванили с использованием INotifyPropertyChanged).
  • Каждый режим привязки для comboboxes.
  • ItemsSource="{Binding}"

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

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

EDIT: По какой-то причине аксессуар набора попадает только в свойство AssetID и только в первый раз. WPF теперь заголовок для WTF :)

EDIT 2: Ты должен быть, шутите мне- я удалил связывание (т.е. только имеет DisplayMemberPath, а valuememberpath и itemssouce), и это все еще делаешь это! Он принимает ваш первый выбор, а затем не изменится.

+0

Вы пытались установить контрольную точку в наборе аксессуаров 'Job.AssetID'? Он попадает? Что происходит, когда вы проходите? Это действительно изменилось? Может быть, это исключение? –

+0

Если я использую Subsonic DAL, он не попадает в аксессуар. Если я использую свой собственный объект, он также не попадает в него, но вокруг прямоугольника появляется красный прямоугольник ... ?? – SteveCav

+0

Убедитесь, что красный прямоугольник исключений был ошибкой типа в моем собственном объекте (Int16 против 32). Так что нет, аксессуар не попадает. – SteveCav

ответ

1

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

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

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

0

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

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

EDIT чтение вашего комментария о красном прямоугольнике - это звучит так, как будто ваша собственность (или что-то связанное с привязкой) создает исключение. Если, конечно, вы не используете проверку данных в своем пользовательском интерфейсе. Вы можете включить «Break on all exceptions» в настройках отладчика, предполагая, что вы используете Visual Studio.

EDIT 2 Вы должны проверить панель вывода VS на наличие сообщений об ошибках, связанных с привязкой. Вы также можете прочитать this blog post, в котором содержится дополнительная информация об установках отладки.

+0

Исключение было несвязанным и было решено. Я «ломаю все исключения» и проверял вывод, но ничего не видел. – SteveCav

+0

Я попытался использовать технику конвертера из сообщения в блоге. Он не попадает в «строку возвращаемого значения» и вместо этого генерирует исключение «этот метод никогда не следует» (только для комманды Asset). Значение в это время является начальным значением AssetID, а не новым выбранным значением. Я понятия не имею, что делать дальше. – SteveCav

+0

Использование уровня трассировки Asset combo возвращает существующее значение, а не выбранное. Другие комбо не производят никакой реакции на реакцию. – SteveCav

0

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

//this.DataContext = oJob; 

и посмотреть, если это помогает.

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

+0

Он все еще делает это даже с удаленным! – SteveCav

0

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

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

+0

Нет, это так странно. Нет стилей, даже никаких событий. Я только что загрузил SS, сгенерировал DAL, создал форму, добавил некоторые комбо, и это не сработало! – SteveCav

3

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

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

1

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

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

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

Его единственный поиск ценности - его значение, которое я получил после.

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