2016-01-28 3 views
0

Я использую Ninject в приложении MVVM, которое содержит свойство Xceed PropertyGrid. PropertyGrid следует использовать пользовательские ItemSource для одного конкретного свойства в настоящее время определенно с атрибутом:PropertyGrid с пользовательскими вставками источника и зависимостей

[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 

Как PropertyGrid не создается 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 

Если я хочу, чтобы придерживаться избегая кода за I единственно возможным способом я вижу, использует инъекции собственности на MainWindow.ListOfSomeObject. Однако это не выглядит правильным.

Я также предполагаю, что такие ситуации возникнут и с различными элементами управления. Существует ли общий абстрактный подход к решению таких проблем для всех элементов управления WPF?

ответ

0

Самое чистое решение, которое я нашел, это использовать шаблон редактирования и привязать его к свойству 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 может быть создан с использованием инъекции свойств или непосредственно с инжектором конструктора.