在 PropertyGrid 控件中显示只读属性

编程入门 行业动态 更新时间:2024-10-25 12:19:20
本文介绍了在 PropertyGrid 控件中显示只读属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用 WPF 扩展工具包来显示 团队 对象的属性.现在这些属性之一是集合 Persons.没问题,我会得到一个不错的下拉菜单,当我点击时,它会显示每个人的姓名和年龄.

现在的问题是我实际上并不想公开我的收藏.但是,一旦我将其设置器设为私有,该属性就会被禁用,以防止用户查看 Person 集合和人员详细信息:

当我的个人集合是私有的时,我应该如何显示它?我可以使用 XAML 模板执行此操作吗?如果是这样怎么办?我正在使用 MVVM,所以我不想在后面的代码中放任何东西.

更新

好的,所以@tencntraze 的解决方案让我完成了大部分工作 - 谢谢.但是,它不适用于我的案例中的对象集合.此外,还可以简化使用 ,所以我只是通过单击按钮显示对话框.

I am using the WPF Extended Toolkit to display the properties of a Team object. Now one of these properties is a collection Persons. No problem I get a nice drop down, which when I click on shows me the names and ages of each of these people.

Now the problem is that I don't actually want to expose my Collection as public. However as soon as I make its setter private the property is disabled preventing the user from seeing the Person collection and the person details:

How should I display my Person Collection when its setter is private? Can I do this with a XAML template? If so how? I'm using MVVM so I don't want to put anything in the code behind.

Update

OK so the solution by @tencntraze got me most of the way there - thanks. However it doesn't work for Collections of objects which is what I've got in my case. In addition it can also be simplified to use the CollectionControlDialog instead of the custom ReadOnlyCollectionViewer that's been implemented below.

XAML

<UserControl x:Class="DevExpressTreeList.ReadOnlyCollectionEditor" xmlns="schemas.microsoft/winfx/2006/xaml/presentation" xmlns:x="schemas.microsoft/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>

Code-Behind

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

解决方案

I think that your best bet here is to implement your own editor, as per the Xceed Documentation. You are then able to provide whatever UI you would like to display to the user without needing to commit the values back to the underlying object. Note that this approach works for both private setters as well as properties without any setter.

ReadOnlyCollectionEditor

XAML

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

Code-Behind

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="schemas.microsoft/winfx/2006/xaml/presentation" xmlns:x="schemas.microsoft/winfx/2006/xaml" Title="ReadOnlyCollectionViewer" Height="300" Width="300"> <ListBox ItemsSource="{Binding Value}" /> </Window>

Sample Properties Class

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; } }

Assigning to the property grid

this.propertyGrid.SelectedObject = new MyDataObjects();

Results

EDIT

I realize that you want to use MVVM, which I strongly encourage when using WPF, but for purposes of this sample I believe that keeping it simple helps illustrate the point, otherwise it brings up other questions like showing a modal dialog from MVVM, so I'm just showing the dialog with a button click.

更多推荐

在 PropertyGrid 控件中显示只读属性

本文发布于:2023-11-12 12:47:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1581534.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控件   属性   PropertyGrid

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!