我有一个使用MEF和MVVMLight的WPF应用程序(.NET 4.5)。共享MEF导出称为" DeviceSupervisor"它包含一个自定义类DeviceConfiguration的ObservableCollection,它不仅仅是一些字符串属性。
在主应用中,您可以在此集合中添加和删除设备。其中一个模块显示ComboBox中的设备列表以供选择。
明确条件:
将用户更改同步到DeviceSupervisor的代码:
foreach (DeviceComplete set in Devices)
{
set.Configuration.CommunicationDetails = set.Device.Value.CommunicationDetails;
if (DeviceSupervisor.AvailableDevices.Any(d => d.ID == set.Configuration.ID))
{
DeviceSupervisor.AvailableDevices
.Single(d => d.ID == set.Configuration.ID)
.CommunicationDetails = set.Configuration.CommunicationDetails;
}
else
{
DeviceSupervisor.AvailableDevices.Add(set.Configuration);
}
}
var missing = new HashSet<DeviceConfiguration>(DeviceSupervisor.AvailableDevices
.Except(Devices.Select(d => d.Configuration)));
foreach (DeviceConfiguration toRemove in missing)
{
// --- TargetException thrown here ---
DeviceSupervisor.AvailableDevices.Remove(toRemove);
}
模块中XAML中的CollectionViewSource:
<CollectionViewSource x:Key="AvailableDevicesCvs"
Source="{Binding Path=AvailableDevices, Mode=OneWay}" Filter="AvailableDevicesCVS_Filter">
</CollectionViewSource>
组合框:
<ComboBox HorizontalAlignment="Left" Margin="10,41,0,0" VerticalAlignment="Top" Width="120"
ItemsSource="{Binding Source={StaticResource AvailableDevicesCvs}}"
SelectedItem="{Binding Path=SelectedDevice}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=CommunicationDetails}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
例外:
未处理的类型&#39; System.Reflection.TargetException&#39;发生在mscorlib.dll中 附加信息:对象与目标类型不匹配。
堆栈跟踪几乎是灰色的所有WindowsBase和PresentationFramework引用。 Intellitrace仅显示我在上面评论的行上抛出的异常。
我的调查结果/其他注释
请注意,如果ComboBox选择了另一个项目,则不会抛出此异常。在任何地方抛出明确的单向绑定都没有任何影响。在我可以在CollectionChanged或Filter事件中抛出的任何断点之前抛出异常。
经过大量的挣扎,重组和反复试验后,我发现如果我只是从组合框中删除ItemTemplate,那么一切都按预期工作 - 没有例外,ComboBox会调整选择以补偿丢失的项目。
我感到紧张,因为我陷入了某个隧道视觉陷阱中,无法看到我犯下的愚蠢错误 - 但更为紧张的是其他东西。
答案 0 :(得分:0)
我已将问题追溯到CommunicationDetails属性。具有该类源文件的库没有对MVVMLight的引用,并且作为获取xyzChanged的快捷方式(对于其他用途)我写了如下属性:
<强>旧强>
private string mCommunicationDetails;
public string CommunicationDetails
{
get
{
return mCommunicationDetails;
}
set
{
bool changed = (mCommunicationDetails != value);
mCommunicationDetails = value;
if (changed)
{
CommunicationDetailsChanged.Raise(this, EventArgs.Empty);
}
}
}
public event EventHandler CommunicationDetailsChanged;
用vanilla {get; set;}属性替换它可以正常工作。我已经用MVVMLight属性替换它
新强>
private string mCommunicationDetails;
public string CommunicationDetails
{
get
{
return mCommunicationDetails;
}
set
{
if (Set(() => CommunicationDetails, ref mCommunicationDetails, value))
{
CommunicationDetailsChanged.Raise(this, EventArgs.Empty);
}
}
}
public event EventHandler CommunicationDetailsChanged;
它有效。
如果有人愿意花时间去寻找或解释这个错误的真正来源,我会接受这个作为答案,但我现在接受这个来解决这个问题。