在PropertyGrid控件中显示只读属性

我正在使用WPF扩展工具包来显示Team对象的属性。 现在其中一个属性是人物集合。 没问题,我得到一个很好的下拉,当我点击时,向我显示每个人的姓名和年龄。

在此处输入图像描述

现在的问题是我实际上并不希望将我的Collection公开为public。 但是,只要我将其setter设为私有,就会禁用该属性,以防止用户看到Person集合和人员详细信息:

在此处输入图像描述

当它的setter是私有的时候我应该如何显示我的Person Collection? 我可以使用XAML模板执行此操作吗? 如果是这样的话? 我正在使用MVVM,所以我不想在代码中添加任何内容。

更新

好的,所以@tencntraze的解决方案让我大部分都在那里 – 谢谢。 但它对于对象的集合不起作用,这是我在我的情况下得到的。 此外,它还可以简化为使用CollectionControlDialog而不是下面实现的自定义ReadOnlyCollectionViewer。

XAML

    

代码隐藏

 public partial class ReadOnlyCollectionEditor : UserControl, ITypeEditor { public ReadOnlyCollectionEditor() { InitializeComponent(); } // Use typeof(object) to allow for any Collection public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof(object), typeof(ReadOnlyCollectionEditor), new PropertyMetadata(default(object))); public object Value { // We are now using object so no need to cast get { return GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public FrameworkElement ResolveEditor(Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem propertyItem) { var binding = new Binding("Value") { Source = propertyItem, Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay }; BindingOperations.SetBinding(this, ValueProperty, binding); return this; } private void Button_OnClick(object sender, RoutedEventArgs e) { var collectionControlDialog = new CollectionControlDialog { ItemsSource = (IList)this.Value }; collectionControlDialog.ShowDialog(); } } 

我认为你最好的选择是根据Xceed文档实现自己的编辑器。 然后,您可以向用户提供要显示的任何UI,而无需将值提交回基础对象。 请注意,此方法适用于私有setter以及没有任何setter的属性。

ReadOnlyCollectionEditor

XAML

    

代码隐藏

 public partial class ReadOnlyCollectionEditor : UserControl, ITypeEditor { public ReadOnlyCollectionEditor() { InitializeComponent(); } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof (IList), typeof (ReadOnlyCollectionEditor), new PropertyMetadata(default(IList))); public IList Value { get { return (IList)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public FrameworkElement ResolveEditor(Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem propertyItem) { var binding = new Binding("Value") { Source = propertyItem, Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay }; BindingOperations.SetBinding(this, ValueProperty, binding); return this; } private void Button_OnClick(object sender, RoutedEventArgs e) { ReadOnlyCollectionViewer viewer = new ReadOnlyCollectionViewer {DataContext = this}; viewer.ShowDialog(); } } 

ReadOnlyCollectionViewer

    

示例属性类

 public class MyDataObjects { public MyDataObjects() { this.CollectionProperty = new Collection {"Item 1", "Item 2", "Item 3"}; this.StringProperty = "Hi!"; } public string StringProperty { get; set; } [Editor(typeof(ReadOnlyCollectionEditor), typeof(ReadOnlyCollectionEditor))] public ICollection CollectionProperty { get; private set; } } 

分配给属性网格

 this.propertyGrid.SelectedObject = new MyDataObjects(); 

结果

主窗口

在此处输入图像描述

编辑

我意识到你想要使用MVVM,我在使用WPF时非常鼓励,但是为了这个示例的目的,我认为保持简单有助于说明这一点,否则它会带来其他问题,比如从MVVM显示modal dialog ,所以我只需单击按钮即可显示对话框。

 public Collection People { get { return _people; } set { throw new NotSupportedException(); } } 

也许不是最好的解决方案,但它可以与PropertyGrid一起使用,同时阻止用户设置新的集合。