在浪费了几个小时之后,继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"
ItemSources
从IQueryables
更改为Lists
。INotifyPropertyChanged
建立我自己的Job对象(普通的vanilla实体类)。ItemsSource="{Binding}"
Subsonic DAL没有实现INotifyPropertyChanged
,但我认为不需要像这样简单绑定。我只是希望能够从下拉列表中选择并保存它。
将它与我上一个问题(此消息顶部的链接)进行比较,我似乎对数据源进行了一些非常奇怪的事情。也许它是亚音速的东西?
编辑:由于某种原因,只有第一次才能在AssetID属性上点击设置访问者。 WPF现在正在前往WTF:)
编辑2:你一定是在开玩笑 - 我已经删除了绑定(即它只有一个displaymember路径,一个valuemember路径和一个itemssouce),它仍然在做它!它接受您的第一个选择,然后不会更改。
答案 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这样的事件并将事件标记为已处理,则可能组合框可能会忽略并且不会选择任何内容。