c# – 在PropertyGrid控件中显示只读属性

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

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

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

更新

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

XAML

<UserControl x:Class="DevExpresstreeList.ReadOnlyCollectionEditor"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Name="MyUserControl"
             >
    <DockPanel>
        <Button Click="Button_OnClick" DockPanel.Dock="Right">
            <Label Content="˅" Padding="2,2,0" />
        </Button>
        <Label Name="CollectionLabel" Content="(Collection)" Padding="2,0" />
    </DockPanel>
</UserControl>

代码隐藏

public partial class ReadOnlyCollectionEditor : UserControl,ITypeEditor
{
    public ReadOnlyCollectionEditor()
    {
        InitializeComponent();
    }

    // Use typeof(object) to allow for any Collection<T>
    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 Documentation实现自己的编辑器.然后你可以提供你想要显示用户的任何UI,而不需要将值提交回底层对象.请注意,此方法适用于私有setter以及没有任何setter的属性.

ReadOnlyCollectionEditor

XAML

<UserControl x:Class="WpfApplication2.ReadOnlyCollectionEditor"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Name="uc">
    <Button Click="Button_OnClick" Height="20" />
</UserControl>

代码隐藏

public partial class ReadOnlyCollectionEditor : UserControl,ITypeEditor
{
    public ReadOnlyCollectionEditor()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
        "Value",typeof (IList<string>),typeof (ReadOnlyCollectionEditor),new PropertyMetadata(default(IList<string>)));

    public IList<string> Value
    {
        get { return (IList<string>)GetValue(ValueProperty); }
        set { SetValue(ValueProperty,RoutedEventArgs e)
    {
        ReadOnlyCollectionViewer viewer = new ReadOnlyCollectionViewer {DataContext = this};
        viewer.ShowDialog();
    }
}

ReadOnlyCollectionViewer

<Window x:Class="WpfApplication2.ReadOnlyCollectionViewer"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ReadOnlyCollectionViewer" Height="300" Width="300">
    <ListBox ItemsSource="{Binding Value}" />
</Window>

示例属性

public class MyDataObjects
{
    public MyDataObjects()
    {
        this.CollectionProperty = new Collection<string> {"Item 1","Item 2","Item 3"};            
        this.StringProperty = "Hi!";
    }

    public string StringProperty { get; set; }

    [Editor(typeof(ReadOnlyCollectionEditor),typeof(ReadOnlyCollectionEditor))]
    public ICollection<string> CollectionProperty { get; private set; } 
}

分配给属性网格

this.propertyGrid.Selectedobject = new MyDataObjects();

结果

编辑

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

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...