WPF Combobox绑定:无法更改选择

时间:2010-06-03 01:49:55

标签: c# wpf data-binding combobox

在浪费了几个小时之后,继Last Problem之后,我开始觉得框架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"
  • 将组合框ItemSourcesIQueryables更改为Lists
  • 使用INotifyPropertyChanged建立我自己的Job对象(普通的vanilla实体类)。
  • 组合框的每种绑定模式。
  • ItemsSource="{Binding}"

Subsonic DAL没有实现INotifyPropertyChanged,但我认为不需要像这样简单绑定。我只是希望能够从下拉列表中选择并保存它。

将它与我上一个问题(此消息顶部的链接)进行比较,我似乎对数据源进行了一些非常奇怪的事情。也许它是亚音速的东西?

编辑:由于某种原因,只有第一次才能在AssetID属性上点击设置访问者。 WPF现在正在前往WTF:)

编辑2:你一定是在开玩笑 - 我已经删除了绑定(即它只有一个displaymember路径,一个valuemember路径和一个itemssouce),它仍然在做它!它接受您的第一个选择,然后不会更改。

6 个答案:

答案 0 :(得分:4)

如果通过在新选择的对象上调用的object.Equals()方法(即newlyslected.Equals(previoslySelected))认为当前所选项目和刚刚选择的项目相等,则WPF组合框不会更改所选项目。

Overriding您绑定组合框项目的类Equals method应解决您所看到的问题。

答案 1 :(得分:1)

我已将其缩小为用作ComboBoxItems的Subsonic对象。 如果您创建的新类使用与Subsonic的相关部分完全相同的代码,则可以正常工作。 如果您对正在编辑的记录使用POCO /数据表作为组合和Subsonic,它可以工作。 但如果您同时使用Subsonic,则不会。

我曾希望扩展亚音速对象而不必编写成熟的BLL层。看起来我正面临这样做或者为DAL抛弃Subsonic。我可能会给亚音速人员发一个更具体的问题。

非常感谢所有贡献者。

答案 2 :(得分:1)

旧主题但我遇到了同样的问题并且难以找到解决方案。这可能会帮助别人。 在WPF中的线索未检测到用户已选择的不同项目。 (症状 - 事件ComboBox_SelectionChanged仅在首次选择时触发)

我的场景 - 从DISTINCT查询构建的IList填充的查找组合。在这种情况下,使用NHibernate ICriteria.SetResultTransformer的结果只返回SOME字段,重要的是不包括唯一的实体ID。

解决方案 - 在检索后循环'IList,并为每个实体提供唯一的ID。 WPF将他们视为个人并且行为恰当。

它只是一个值查找 - 它是我追求的价值内容。

“临时”实体永远不会被保留。在这种情况下,为了简单的GUI问题,这是一种比干扰覆盖对象的Equals方法更好的方法。另一种方法是将列表复制或转换为WPF使用值字段来确定“差异”的格式......

答案 3 :(得分:0)

听起来这个字段是以某种方式只读,或者你的更改没有被持久化。绑定设置新值后,它将重新读取属性以确保它实际更改。如果你的属性返回旧值,那么它将在组合框中重新选择,给出值永远不会改变的外观。

我不知道DAL,但你可以单步执行属性设置器代码吗?您可能还遇到类型转换问题。

编辑阅读关于红色矩形的评论 - 听起来好像你的属性(或与绑定有关的东西)引发异常。当然,除非您在UI中使用数据验证。假设您正在使用Visual Studio,您可能会在调试器的设置中打开“Break on all exceptions”。

编辑2 您应该在“VS输出”窗格中查看与绑定相关的任何错误消息。您还可以阅读this blog post,其中提供了有关调试绑定的更多信息。

答案 4 :(得分:0)

很难从代码的一小部分样本中判断出来,但尝试评论这一行:

//this.DataContext = oJob; 

看看这是否有帮助。

设置DataContext和ItemsSource可能会导致冲突。

答案 5 :(得分:0)

你是否为你的组合框写了任何可能有错误或遗漏的全局样式?或者您使用纯组合框的默认样式?尝试删除所有应用的默认样式。

您是否正在联系任何活动?如果您的代码挂起了像PreviewMouseLeftButtonUp这样的事件并将事件标记为已处理,则可能组合框可能会忽略并且不会选择任何内容。