【发布时间】:2015-09-09 22:28:31
【问题描述】:
我正在开发一个简单的 WPF 应用程序。目前,该应用程序仅管理 ComboBox 中的视频游戏列表。游戏列表与 XML 文件进行序列化。
目前被破坏的功能是能够从 ComboBox 中选择一个游戏,使其成为要管理的“活动”游戏。活动游戏将存储为应用程序设置。为此,我使用双向数据绑定并将 ComboBox 中的 SelectedItem 绑定到 ViewModel 中的 SelectedGame。
当我运行应用程序并从 ComboBox 中选择一个项目时,我在 Game.Equals(Game other) 方法上得到一个空引用异常。在调试时,我看到 DependencyProperty.UnsetValue 作为参数传递给覆盖的 Game.Equals(object obj) 方法,这导致 obj as Game 使 obj 为 null。
我不明白为什么当我所做的只是从 ComboBox 值中选择一个项目时,为什么首先调用 Equals,所以我猜它是 WPF 原生的东西。在前往 Equals 方法之前,该代码似乎没有遇到任何其他断点,所以我什至不确定如何调试该问题。我也不明白 DependencyProperty.UnsetValue 来自哪里。我完全迷失了这里,希望有任何见解,包括我如何进一步调试。
编辑: 正如 Glen 所暗示的,Equals 必须由 WPF 的某些底层组件调用。至少目前,我的解决方案是简单地向我的 Equals 覆盖添加一个空检查。
模型类
public class Game : IEntity, IEquatable<Game>
{
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("ExecutablePath")]
public string ExecutablePath { get; set; }
public Game(string name, string executablePath)
{
Name = name;
ExecutablePath = executablePath;
}
private Game() { } // Required for XML serialization.
public bool Equals(Game other)
{
return Name.EqualsIgnoreCase(other.Name);
}
public override bool Equals(object obj)
{
return Equals(obj as Game);
}
}
视图模型
public class GamesViewModel
{
// The GameRepository retrieves the game collection from the XML file.
private readonly GameRepository _gameRepository;
public ObservableCollection<Game> Games
{
get { return new ObservableCollection<Game>(_gameRepository.Items); }
}
public Game SelectedGame
{
get { return Settings.Default.ActiveGame; }
set
{
if (!Settings.Default.ActiveGame.Equals(value))
{
Settings.Default.ActiveGame = value;
Settings.Default.Save();
}
}
}
public GamesViewModel()
{
_gameRepository = RepositorySingletons.GameRepository;
}
}
查看
<UserControl x:Class="ENBOrganizer.UI.Views.GamesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ENBOrganizer.UI.ViewModels"
mc:Ignorable="d" >
<UserControl.DataContext>
<local:GamesViewModel />
</UserControl.DataContext>
<Grid>
<ComboBox Name="GamesComboBox" ItemsSource="{Binding Games}" SelectedItem="{Binding SelectedGame}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Padding="5,0,0,0" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</UserControl>
【问题讨论】:
-
您的 Equals 方法非常懒惰。您应该能够在不抛出 NRE 的情况下处理此问题。
-
我可以接受空检查。我只是想了解为什么首先要传入 null。