【问题标题】:WPF Combobox binding: can't change selectionWPF组合框绑定:无法更改选择
【发布时间】:2010-06-03 01:49:55
【问题描述】:

在我的Last Problem 之后浪费了几个小时之后,我开始觉得Framework 4 是微妙邪恶的大师,或者我的PC 闹鬼了。

我在 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
  • 构建我自己的 Job 对象(使用 INotifyPropertyChanged 的普通实体类)。
  • 组合框的每种绑定模式。
  • ItemsSource="{Binding}"

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

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

编辑: 出于某种原因,set 访问器仅在 AssetID 属性上被命中,并且仅在第一次被命中。 WPF 现在正走向 WTF :)

编辑 2: 你一定是在开玩笑吧——我已经删除了绑定(即它只有一个 displaymemberpath、一个 valuememberpath 和一个 itemssouce)而且它还在做!它接受您的第一个选择,然后不会更改。

【问题讨论】:

  • 您是否尝试在Job.AssetID 的set 访问器中设置断点?是不是被击中了?当你通过时会发生什么?它真的改变了吗?也许它会引发异常?
  • 如果我使用 Subsonic DAL,它不会击中存取器。如果我使用自己的对象,它也不会击中它,但组合框周围会出现一个红色矩形...??
  • 检查 - 红色异常矩形是我自己的对象中的类型错误(Int16 vs 32)。所以不,访问器没有被击中。
  • 查看对我的回答的编辑,了解您的绑定可能有什么问题。

标签: c# wpf data-binding combobox


【解决方案1】:

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

Overriding Equals method 在您绑定组合框项目的类上,应该可以解决您看到的问题。

【讨论】:

    【解决方案2】:

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

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

    非常感谢所有做出贡献的人。

    【讨论】:

      【解决方案3】:

      老话题,但我遇到了同样的问题并且很难找到解决方案。这可能对其他人有帮助。 上面的线索在 WPF 中没有检测到用户选择了不同的项目。 (症状 - ComboBox_SelectionChanged 事件仅在第一次选择时触发)

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

      解决方案 - 检索后通过 IList 循环,并为每个实体提供唯一 ID。 WPF 将他们视为个体并表现得恰当。

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

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

      【讨论】:

        【解决方案4】:

        听起来该字段在某种程度上是只读的,或者您的更改没有被持久化。绑定设置新值后,它会重新读取属性以确保它确实被更改了。如果您的属性返回旧值,那么它将在组合框中重新选择,呈现出该值从未更改过的外观。

        我不知道那个 DAL,但你能单步调试一下属性设置器代码吗?您可能还会遇到类型转换问题。

        EDIT 阅读您对红色矩形的评论 - 听起来您的属性(或与绑定有关的东西)正在引发异常。当然,除非您在 UI 中使用数据验证。假设您使用的是 Visual Studio,您可以在调试器的设置中打开“中断所有异常”。

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

        【讨论】:

        • 异常无关,已解决。我“打破所有异常”并检查了输出但什么也没看到。
        • 我尝试使用博客文章中的转换器技术。它没有命中“返回值行”,而是抛出“永远不应调用此方法”异常(仅适用于资产组合)。当时的值是 AssetID 的初始值,而不是新选择的值。我不知道下一步该做什么。
        • 使用跟踪级别,资产组合返回现有值而不是选定的值。其他组合根本不会产生微量反应。
        【解决方案5】:

        很难从您的代码的一小部分示例中分辨出来,但请尝试注释掉该行:

        //this.DataContext = oJob; 
        

        看看这是否有帮助。

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

        【讨论】:

        • 即使两个都被删除了,它仍然会这样做!
        【解决方案6】:

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

        您是否正在安排任何事件?如果您的代码连接到 PreviewMouseLeftButtonUp 之类的事件并将事件标记为已处理,那么组合框可能会忽略并且不会选择任何内容。

        【讨论】:

        • 不,这就是令人困惑的地方。没有样式,甚至没有任何事件。我刚刚下载了SS,生成了DAL,创建了一个表单,添加了一些combo,结果还是不行!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-25
        • 2018-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        相关资源
        最近更新 更多