在PropertyGrid控件中显示只读属性

15 浏览
0 Comments

在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 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();
    }
}

0
0 Comments

问题的原因是PropertyGrid控件无法显示只读属性,因为它默认会提供一个可编辑的文本框供用户输入。在上述代码中,People属性只有getter方法,没有setter方法,因此它是只读的。然而,PropertyGrid控件无法识别这一点,因此无法正确显示该属性。

解决方法是使用Browsable特性来告诉PropertyGrid控件是否应该显示该属性。可以在People属性上添加Browsable特性,并将其设置为false,以指示该属性不应在PropertyGrid中显示。代码如下:

[Browsable(false)]
public Collection People
{
    get { return _people; }
    set { throw new NotSupportedException(); }
}

通过添加Browsable特性并将其设置为false,PropertyGrid控件将不再显示该属性,从而解决了只读属性无法显示的问题。

0
0 Comments

在使用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控件中显示只读属性的方法,并提供了一个示例代码来说明如何实现一个只读集合编辑器。

0