在PropertyGrid控件中显示只读属性
在PropertyGrid控件中显示只读属性
我正在使用WPF扩展工具包来显示一个Team对象的属性。现在其中一个属性是一个Persons集合。没问题,我得到了一个漂亮的下拉菜单,当我点击它时,它会显示每个人的姓名和年龄。
现在的问题是,我实际上不想将我的集合公开。但是,一旦我将其setter设置为私有,属性就会被禁用,阻止用户查看Person集合和人员详细信息:
如何在将其setter设置为私有时显示我的Person集合?我可以用XAML模板做到这一点吗?如果可以,怎么做?我正在使用MVVM,所以不想在代码中添加任何东西。
更新
好的,@tencntraze提供的解决方案帮助了我很大一部分-谢谢。
然而,它对于我所拥有的对象集合不起作用。此外,还可以简化使用CollectionControlDialog而不是下面实现的自定义ReadOnlyCollectionViewer。
XAML
代码后台
public partial class ReadOnlyCollectionEditor : UserControl, ITypeEditor { public ReadOnlyCollectionEditor() { InitializeComponent(); } // Use typeof(object) to allow for any Collectionpublic 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(); } }
问题的原因是PropertyGrid控件无法显示只读属性,因为它默认会提供一个可编辑的文本框供用户输入。在上述代码中,People属性只有getter方法,没有setter方法,因此它是只读的。然而,PropertyGrid控件无法识别这一点,因此无法正确显示该属性。
解决方法是使用Browsable特性来告诉PropertyGrid控件是否应该显示该属性。可以在People属性上添加Browsable特性,并将其设置为false,以指示该属性不应在PropertyGrid中显示。代码如下:
[Browsable(false)] public CollectionPeople { get { return _people; } set { throw new NotSupportedException(); } }
通过添加Browsable特性并将其设置为false,PropertyGrid控件将不再显示该属性,从而解决了只读属性无法显示的问题。
在使用PropertyGrid控件中显示只读属性时,可能会遇到一些问题。解决这些问题的方法是实现自己的编辑器,如Xceed文档所述。这样,您可以提供自己想要显示给用户的任何UI,而无需将值提交回底层对象。请注意,此方法适用于具有私有setters以及没有任何setter的属性。
下面是一个实现只读集合编辑器的示例代码:
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(); } }
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();
使用以上代码将MyDataObjects类的实例赋值给propertyGrid的SelectedObject属性后,会在PropertyGrid控件中显示只读属性。
以上是解决在PropertyGrid控件中显示只读属性的方法,并提供了一个示例代码来说明如何实现一个只读集合编辑器。