【问题标题】:PropertyGrid with custom Itemsource and Dependency Injection具有自定义 Itemsource 和依赖注入的 PropertyGrid
【发布时间】:2016-05-05 17:47:59
【问题描述】:

我在包含 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

由于 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

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

我也猜想这种情况也会出现在不同的控件中。是否有一种通用的抽象方法来解决所有 WPF 控件的此类问题?

【问题讨论】:

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


    【解决方案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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      • 2019-07-12
      • 2014-01-30
      • 2013-07-14
      • 1970-01-01
      • 2017-10-19
      相关资源
      最近更新 更多