具有自定义Itemsource和Dependency Injection

时间:2016-01-28 11:17:08

标签: wpf vb.net dependency-injection propertygrid xceed

我在包含Xceed PropertyGrid的MVVM应用程序中使用Ninject。 PropertyGrid应该为当前使用Attribute:

定义的一个特定属性使用自定义ItemSource
[ItemSource(GetType(SomeObjectItemSource)] 

SomeObjectItemSource.GetValues看起来像那样,需要访问使用Ninject创建的对象

Public Function GetValues() As ItemCollection Implements IItemsSource.GetValues

    Fetch RootObject from Ninject Kernel
    Extract a list of SomeObject from RootObject and Return

End Function

由于PropertyNrid不是由Ninject创建的,并且Ninject在内部使用Activator.CreateInstance而没有任何可选的构造函数参数,因此我无法将引用传递给Ninject内核或RootObject。

注意:PropertyGrid的源代码如下所示。 Activate.CreateInstance可以使用构造函数,但是没有这样实现。

private System.Collections.IEnumerable CreateItemsSource()
{
  var instance = Activator.CreateInstance( _attribute.Type );
  return ( instance as IItemsSource ).GetValues();
}

或者,可以使用ITypeEditor使用自定义类型编辑器,并将编辑器绑定到创建PropertyGrid的实例的属性。这里建议采用这种方法:http://wpftoolkit.codeplex.com/discussions/351513,看起来像:

Public Class SomeObjectTypeEditor
  Implements ITypeEditor
  Public Function ResolveEditor(propertyItem As PropertyItem) As FrameworkElement
    Dim box As New ComboBox() With { _
     .DisplayMemberPath = "SomeObject" _
    }

    Dim itemSourcebinding = New Binding("") With { _
        .Source = MainWindow.ListOfSomeObject , _
        .ValidatesOnExceptions = True, _
        .ValidatesOnDataErrors = True, _
        .Mode = BindingMode.OneWay _
    }
  End Function
End Class

如果我想坚持避免代码,我看到唯一可行的方法就是在MainWindow.ListOfSomeObject上使用属性注入。然而,这对我来说并不合适。

我也猜测这种情况也会出现在不同的控制之下。是否有一个共同的,抽象的方法来解决所有WPF控件的问题?

1 个答案:

答案 0 :(得分:1)

我发现最干净的解决方案是使用编辑模板并绑定到ViewModel的属性。

<xctk:EditorTemplateDefinition.EditingTemplate>
    <DataTemplate>
        <ComboBox Name="Combo" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ListOfSomeObject}"
                                             DisplayMemberPath="ObjectName"
                                             SelectedValuePath="ObjectID" />
    </DataTemplate>
</xctk:EditorTemplateDefinition.EditingTemplate>

使用这种方法可以使用属性注入或直接使用构造函数注入来创建ListOfSomeObject。