【发布时间】:2011-09-02 23:35:14
【问题描述】:
我有一个具有许多属性的Activity 对象。其中之一如下:
public ActivityStatus Status
{
get { return status; }
set { status = value; NotifyPropertyChanged("Status"); }
}
ActivityStatus 类只有两个属性:
public Guid Guid
{
get { return guid; }
set { guid = value; NotifyPropertyChanged("Guid"); }
}
public string Name
{
get { return name; }
set { name = value; NotifyPropertyChanged("Name"); }
}
和Equals 方法:
public override bool Equals(object otherObject)
{
if (!(otherObject is ActivityStatus)) return false;
return Equals(otherObject as ActivityStatus);
}
public bool Equals(ActivityStatus otherStatus)
{
if (!(otherStatus is ActivityStatus) || otherStatus == null) return false;
return Guid == otherStatus.Guid && Name == otherStatus.Name;
}
我有一个ActivityViewModel 类作为ActivityView 类的DataContext。 ActivityViewModel 有一个Activity 类型为Activity 的属性,除此之外还有一个ActivityStatuses 类型为ObservableCollection<ActivityStatus> 的属性。在ActivityView 我有一个ComboBox 声明如下:
<ComboBox ItemsSource="{Binding ActivityStatuses}"
SelectedItem="{Binding Activity.Status, Mode=TwoWay}"
DisplayMemberPath="Name" />
这允许我从ComboBox 中选择一个ActivityStatus,这会正确更新视图模型的Activity 属性中Activity 的Status 属性。问题在于双向绑定...加载新的Activity 时,ComboBox.SelectedItem 不会更新以显示Activity.Status 属性值。
使用ComboBox 的此声明,SelectedItem 绑定到Activity 中的ActivityStatus 对象,这是与视图模型ActivityStatuses 属性中具有相同值的对象不同的对象。因此 WPF 框架不认为项目相同,不会选择 ComboBox 中的项目。
如果我在加载每个Activity 后将具有相同值的集合中的项目分配给Activity.Status 属性,则ComboBox 在其ItemsSource 集合中找到匹配项并正确设置SelectedItem 属性显示值。我真的不想这样做,因为我在Activity 类中有许多其他类似的属性,我必须在任何我想双向绑定到ComboBoxes 的地方重复此代码。
所以我也尝试绑定到ActivityStatus.Guid 属性,如下所示:
<ComboBox ItemsSource="{Binding ActivityStatuses}"
SelectedValue="{Binding Activity.Status.Guid, Mode=TwoWay}"
SelectedValuePath="Guid"
DisplayMemberPath="Name" />
当加载不同的Activity 对象时,这会正确地从ComboBox.ItemsSource 集合中选择具有相同Guid 的对象作为Activity.Status 属性中的对象。这种方法的问题是SelectedValue 绑定到ActivityStatus 对象中的ActivityStatus.Guid 属性,因此在UI 中更改值时,只有ActivityStatus 对象的'Guid' 属性会更新,保持名称不变。 Activity.Status 属性中的对象除了其Guid 属性的值外没有变化。
如您所见,我还尝试实现Equals 方法,因为我假设ComboBox 会使用它来比较对象,但它没有任何区别。所以最后,我不知所措并渴望找到一种简单干净的方法来解决这个问题......希望有一个我在ComboBox 上错过的简单属性。
我只是希望能够在ComboBox 中选择一个项目并相应地更改Activity.Status 对象并从代码中更改Activity.Status 属性的值并让ComboBox.SelectedItem 也相应地更新。如有任何建议,我将不胜感激。
更新>>>
阅读 Will 的回复后,我在新解决方案中尝试了他的代码示例,发现它按预期工作。然后我彻底检查了他的代码,发现它和我的一样,所以再次运行了我自己的解决方案(这是自这篇文章以来的第一次)。令我完全惊讶的是,它按预期工作,无需我更改任何代码!
这让我非常困惑,我花了一些时间才知道发生了什么。事实证明,问题是/是 Visual Studio 2010!作为最后阶段,我已将 Equals 方法添加到我的数据类型中。由于某种原因,Visual Studio 在运行应用程序时没有构建数据类型项目。
所以应用程序一定是在使用旧的 dll 文件,而我的更改没有被使用...我确实想知道为什么我在 Equals 方法上的断点从未被命中。这导致我假设实施Equals 方法没有帮助。 Visual Studio 今天也有同样的行为,这就是我发现发生了什么的方式。
我在我的解决方案中检查了项目构建顺序,但它在顺序中的正确位置列出了数据类型项目。但是,在运行应用程序时,Visual Studio 中的“输出”窗口会显示项目 dll 以不同的顺序加载。我不确定为什么运行应用程序不再进行完整的构建,但至少我知道在运行应用程序之前我必须在对其进行更改之后构建该项目。
最终更新>>>
我刚刚发现为什么我的数据类型项目没有构建...我查看了配置管理器窗口,发现平台对于该项目不正确,并且构建复选框已被取消选中!我不知道这是怎么发生的,但我终于找到了问题的根源,这让我松了一口气。
【问题讨论】:
-
您在这里遇到的是经典的“项目引用/文件引用”问题。您应该删除解决方案中对其他项目的所有引用,并将它们重新添加为项目引用。文件引用不会在构建或更改构建类型(例如,调试/发布)时自动更新。 永远不要浏览到 /bin 目录来添加引用! 更多关于项目引用的信息check this msdn article
-
谢谢@Will,但我刚刚发现为什么我的数据类型项目没有构建...我查看了配置管理器窗口,发现平台对于该项目和构建复选框不正确已经变得不受控制了!我不知道这是怎么发生的,但我终于找到了问题的根源,这让我松了一口气。
标签: c# wpf data-binding mvvm combobox