新属性的替代模式(AmbiguousMatchException)

时间:2014-04-04 10:12:06

标签: c# wpf mvvm

我使用以下模式根据具体的模型实例一般性地创建基本视图mdoel的专用实例:

#region Model

public class Model
{

}

public class DerivedModel : Model
{

}

#endregion

#region ViewModel

public abstract class ViewModel
{
    public static ViewModel Create(Model model)
    {
        return (ViewModel)CreateInternal((dynamic) model);
    }

    private static ViewModel<TModel> CreateInternal<TModel>(TModel model)
    {
        var viewModel = IoC.Get<ViewModel<DerivedModel>>();
        viewModel.Model = model;
        return viewModel;
    }

    public Model Model { get { return GetModel(); } }
    internal abstract Model GetModel();
}

public abstract class ViewModel<TModel> : ViewModel where TModel : Model
{
    public new TModel Model { get; internal set; }
    internal override Model GetModel() { return Model; }
}

[Export(typeof(ViewModel<DerivedModel>))]
/*private*/ class MySpecializedModel : ViewModel<DerivedModel>
{
    //specialization
}

#endregion

这个想法是通过MEF实现它们,因此不需要知道conMcete ViewModel Type,并且可以在其他程序集中定义特化并在运行时插入程序。

但是,当我尝试绑定到Model属性时,我在wpf框架内部的某个地方得到了一个AmbiguousMatchException(实际上,绑定本身并没有失败,但是MeasureOverride中的某些代码试图通过反射访问该属性): / p>

System.Reflection.AmbiguousMatchException occurred
Source=mscorlib
StackTrace:
mscorlib.dll!System.RuntimeType.GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) + 0x127 bytes   
mscorlib.dll!System.Type.GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + 0x1f bytes  
PresentationFramework.dll!System.Windows.PropertyPath.GetPropertyHelper(System.Type ownerType, string propertyName) + 0x31 bytes    
PresentationFramework.dll!System.Windows.PropertyPath.ResolvePropertyName(string name, object item, System.Type ownerType, object context, bool throwOnError) + 0x8e bytes  
PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.GetInfo(int k, object item, ref MS.Internal.Data.PropertyPathWorker.SourceValueState svs) + 0x3b5 bytes   
PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.ReplaceItem(int k, object newO, object parent) + 0x302 bytes  
PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(int k, System.ComponentModel.ICollectionView collectionView, object newValue, bool isASubPropertyChange) + 0xea bytes  
PresentationFramework.dll!MS.Internal.Data.ClrBindingWorker.AttachDataItem() + 0x9e bytes   
PresentationFramework.dll!System.Windows.Data.BindingExpression.Activate(object item) + 0x10d bytes 
PresentationFramework.dll!System.Windows.Data.BindingExpression.AttachToContext(System.Windows.Data.BindingExpression.AttachAttempt attempt) + 0x33a bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpression.AttachOverride(System.Windows.DependencyObject target, System.Windows.DependencyProperty dp) + 0xd1 bytes   
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.OnAttach(System.Windows.DependencyObject d, System.Windows.DependencyProperty dp) + 0x38 bytes  
PresentationFramework.dll!System.Windows.StyleHelper.GetInstanceValue(System.Windows.UncommonField<System.Collections.Specialized.HybridDictionary[]> dataField, System.Windows.DependencyObject container, System.Windows.FrameworkElement feChild, System.Windows.FrameworkContentElement fceChild, int childIndex, System.Windows.DependencyProperty dp, int i, ref System.Windows.EffectiveValueEntry entry) + 0x1a5 bytes  
PresentationFramework.dll!System.Windows.StyleHelper.GetChildValueHelper(System.Windows.UncommonField<System.Collections.Specialized.HybridDictionary[]> dataField, ref MS.Utility.ItemStructList<System.Windows.ChildValueLookup> valueLookupList, System.Windows.DependencyProperty dp, System.Windows.DependencyObject container, MS.Internal.FrameworkObject child, int childIndex, bool styleLookup, ref System.Windows.EffectiveValueEntry entry, out System.Windows.ValueLookupType sourceType, System.Windows.FrameworkElementFactory templateRoot) + 0x4e7 bytes   
PresentationFramework.dll!System.Windows.StyleHelper.GetChildValue(System.Windows.UncommonField<System.Collections.Specialized.HybridDictionary[]> dataField, System.Windows.DependencyObject container, int childIndex, MS.Internal.FrameworkObject child, System.Windows.DependencyProperty dp, ref MS.Utility.FrugalStructList<System.Windows.ChildRecord> childRecordFromChildIndex, ref System.Windows.EffectiveValueEntry entry, out System.Windows.ValueLookupType sourceType, System.Windows.FrameworkElementFactory templateRoot) + 0xbc bytes 
PresentationFramework.dll!System.Windows.StyleHelper.GetValueFromTemplatedParent(System.Windows.DependencyObject container, int childIndex, MS.Internal.FrameworkObject child, System.Windows.DependencyProperty dp, ref MS.Utility.FrugalStructList<System.Windows.ChildRecord> childRecordFromChildIndex, System.Windows.FrameworkElementFactory templateRoot, ref System.Windows.EffectiveValueEntry entry) + 0x52 bytes 
PresentationFramework.dll!System.Windows.StyleHelper.ApplyTemplatedParentValue(System.Windows.DependencyObject container, MS.Internal.FrameworkObject child, int childIndex, ref MS.Utility.FrugalStructList<System.Windows.ChildRecord> childRecordFromChildIndex, System.Windows.DependencyProperty dp, System.Windows.FrameworkElementFactory templateRoot) + 0x78 bytes 
PresentationFramework.dll!System.Windows.StyleHelper.InvalidatePropertiesOnTemplateNode(System.Windows.DependencyObject container, MS.Internal.FrameworkObject child, int childIndex, ref MS.Utility.FrugalStructList<System.Windows.ChildRecord> childRecordFromChildIndex, bool isDetach, System.Windows.FrameworkElementFactory templateRoot) + 0x8c bytes   
PresentationFramework.dll!System.Windows.FrameworkTemplate.InvalidatePropertiesOnTemplate(System.Windows.DependencyObject container, object currentObject) + 0xcf bytes 
PresentationFramework.dll!System.Windows.FrameworkTemplate.HandleBeforeProperties(object createdObject, ref System.Windows.DependencyObject rootObject, System.Windows.DependencyObject container, System.Windows.FrameworkElement feContainer, System.Windows.Markup.INameScope nameScope) + 0x2d bytes    
PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent.AnonymousMethod__3(object sender, System.Xaml.XamlObjectEventArgs args) + 0x24 bytes    
System.Xaml.dll!System.Xaml.XamlObjectWriter.OnBeforeProperties(object value) + 0x46 bytes  
System.Xaml.dll!System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(MS.Internal.Xaml.Context.ObjectWriterContext ctx) + 0xfe bytes  
System.Xaml.dll!System.Xaml.XamlObjectWriter.WriteEndObject() + 0x2ae bytes 
System.Xaml.dll!System.Xaml.XamlWriter.WriteNode(System.Xaml.XamlReader reader) + 0x65 bytes    
PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlReader templateReader, System.Xaml.XamlObjectWriter currentWriter) + 0x41 bytes 
PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlObjectWriter objectWriter) + 0x61 bytes 
PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(System.Windows.DependencyObject container, System.Windows.Markup.IComponentConnector componentConnector, System.Windows.Markup.IStyleConnector styleConnector, System.Collections.Generic.List<System.Windows.DependencyObject> affectedChildren, System.Windows.UncommonField<System.Collections.Hashtable> templatedNonFeChildrenField) + 0x259 bytes 
PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadContent(System.Windows.DependencyObject container, System.Collections.Generic.List<System.Windows.DependencyObject> affectedChildren) + 0x7b bytes   
PresentationFramework.dll!System.Windows.StyleHelper.ApplyTemplateContent(System.Windows.UncommonField<System.Collections.Specialized.HybridDictionary[]> dataField, System.Windows.DependencyObject container, System.Windows.FrameworkElementFactory templateRoot, int lastChildIndex, System.Collections.Specialized.HybridDictionary childIndexFromChildID, System.Windows.FrameworkTemplate frameworkTemplate) + 0xa5 bytes    
PresentationFramework.dll!System.Windows.FrameworkTemplate.ApplyTemplateContent(System.Windows.UncommonField<System.Collections.Specialized.HybridDictionary[]> templateDataField, System.Windows.FrameworkElement container) + 0x3b bytes  
PresentationFramework.dll!System.Windows.FrameworkElement.ApplyTemplate() + 0x7c bytes  
PresentationFramework.dll!System.Windows.FrameworkElement.MeasureCore(System.Windows.Size availableSize) + 0x40 bytes   
PresentationCore.dll!System.Windows.UIElement.Measure(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationFramework.dll!System.Windows.Controls.Control.MeasureOverride(System.Windows.Size constraint) + 0x60 bytes  
PresentationFramework.dll!System.Windows.FrameworkElement.MeasureCore(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationCore.dll!System.Windows.UIElement.Measure(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationFramework.dll!System.Windows.Controls.Grid.MeasureOverride(System.Windows.Size constraint) + 0x281 bytes    
PresentationFramework.dll!System.Windows.FrameworkElement.MeasureCore(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationCore.dll!System.Windows.UIElement.Measure(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationFramework.dll!System.Windows.Controls.Grid.MeasureCell(int cell, bool forceInfinityV) + 0xe9 bytes  
PresentationFramework.dll!System.Windows.Controls.Grid.MeasureCellsGroup(int cellsHead, System.Windows.Size referenceSize, bool ignoreDesiredSizeU, bool forceInfinityV, out bool hasDesiredSizeUChanged) + 0x8a bytes  
PresentationFramework.dll!System.Windows.Controls.Grid.MeasureOverride(System.Windows.Size constraint) + 0x3e6 bytes    
PresentationFramework.dll!System.Windows.FrameworkElement.MeasureCore(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationCore.dll!System.Windows.UIElement.Measure(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationFramework.dll!System.Windows.Controls.Grid.MeasureCell(int cell, bool forceInfinityV) + 0xe9 bytes  
PresentationFramework.dll!System.Windows.Controls.Grid.MeasureCellsGroup(int cellsHead, System.Windows.Size referenceSize, bool ignoreDesiredSizeU, bool forceInfinityV, out bool hasDesiredSizeUChanged) + 0x8a bytes  
PresentationFramework.dll!System.Windows.Controls.Grid.MeasureOverride(System.Windows.Size constraint) + 0x3e6 bytes    
PresentationFramework.dll!System.Windows.FrameworkElement.MeasureCore(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationCore.dll!System.Windows.UIElement.Measure(System.Windows.Size availableSize) + 0x1cc bytes  
PresentationFramework.dll!System.Windows.Controls.Control.MeasureOverride(System.Windows.Size constraint) + 0x60 bytes  >   Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadTreeViewItem.MeasureOverride(System.Windows.Size availableSize) Line 1537 + 0x28 bytes

...

因此,使用一些搜索继承链的用户定义函数的答案,例如,正如线程AmbiguousMatchException - Type.GetProperty - C# Reflection中提出的那样,不适用于此。

如何实现模式以便我可以从专用的viewmodel类中访问专用的Model属性,还可以从基本视图模型中访问基本属性?重命名属性看起来很难看,因为它指向同一个对象!

0 个答案:

没有答案