簡體   English   中英

在PropertyGrid控件中顯示只讀屬性

[英]Displaying read only properties in PropertyGrid control

我正在使用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,0,2,0" />
        </Button>
        <Label Name="CollectionLabel" Content="(Collection)" Padding="2,2,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文檔實現自己的編輯器。 然后,您可以向用戶提供要顯示的任何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, 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

<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時非常鼓勵,但是為了這個示例的目的,我認為保持簡單有助於說明這一點,否則它會帶來其他問題,比如從MVVM顯示模態對話框 ,所以我只需點擊一下按鈕即可顯示對話框。

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

也許不是最好的解決方案,但它可以與PropertyGrid一起使用,同時阻止用戶設置新的集合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM