WPF中实现PropertyGrid的三种方式

   由于WPF中没有提供PropertyGrid控件,有些业务需要此类的控件。这篇文章介绍在WPF中实现PropertyGrid的三种方式,三种方式都是俺平时使用时总结出来的。

     第一种方式:使用WindowsForm的PropertyGrid控件。

     用过WPF的童鞋都晓得,可以通过WindowsFormsHost将WindowsForm的控件宿主到WPF中使用。很简单,分为简单的3步。

     第一步:引用dll:在WPF应用程序中引入System.Windows.Forms.dll。

     第二步:引用命名空间:在窗体的.cs代码中引用此命名空间:using System.Windows.Forms;在XAML中引用此命名空间代码如下:

xmlns:my="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

      第三步:通过WindowsFormsHost使用PropertyGrid控件。 

WPF中实现PropertyGrid的三种方式代码
<WindowsFormsHost Height="287" HorizontalAlignment="Left" Margin="18,12,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="200">
<my:PropertyGrid x:Name="PropertyGrid1"></my:PropertyGrid> 
</WindowsFormsHost>

    看下效果Button的属性:

WPF中实现PropertyGrid的三种方式

将Button的背景色设置为红色:

WPF中实现PropertyGrid的三种方式

第二种方式:自定义WPF控件。这里以codeplex上的一个开源控件为例。如果你想知道实现的细节,可以到http://wpg.codeplex.com/上下载代码学习。

使用方式很简单。由于它是WPF控件,所以不需要使用WindowsFormsHost。

WPF中实现PropertyGrid的三种方式
WPF中实现PropertyGrid的三种方式代码
<Window x:Class="WPGDemoApp.Window1"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpg
="clr-namespace:WPG;assembly=WPG"
Title
="Window1" Height="300" Width="300">
<DockPanel VerticalAlignment="Stretch">
<Button DockPanel.Dock="Top" x:Name="btn">button for test</Button>
<wpg:PropertyGrid DockPanel.Dock="Top" Instance="{Binding ElementName=btn}" VerticalAlignment="Stretch" IsEnabled="True"></wpg:PropertyGrid>
</DockPanel>
</Window>
WPF中实现PropertyGrid的三种方式

把Button的背景色设置为红色:

WPF中实现PropertyGrid的三种方式

 第三种方式:使用WF4.0设计器里面的属性框控件。WF4.0的流程设计器有一个这样的PropertyGrid控件。我们利用它来实现自己的PropertyGrid控件。这也是本文重点介绍的方式。参考:Native WPF 4 PropertyGrid。分五个步骤去实现。

1、自定义一个用户控件,这个控件继承Grid类。grid将包含真正的界面元素。

2、用Workflow Foundation的WorkflowDesigner一个对象作为这个控件的私有成员。

3、对于需要设计的对象,在grid中添加一个PropertyInspectorView对象的子元素。对外它是一个Grid,其实它的类型是ProperyInspector。

4、通过反射获取和使用PropertyInspector的一些方法。

5、实现一个SelectedObject属性,标准的PropertyGrid都有它。用来处理PropertyInspector选择对象的改变。

代码如下:

WPF中实现PropertyGrid的三种方式
WPF中实现PropertyGrid的三种方式代码
using System.Activities.Presentation;
using System.Activities.Presentation.Model;
using System.Activities.Presentation.View;
using System.Reflection;
using System.Windows.Controls;

namespace System.Windows.Control
{
///<summary>
/// WPF Native PropertyGrid class, taken from Workflow Foundation Designer
///</summary>
publicclass WpfPropertyGrid : Grid
{
#region Private fields
private WorkflowDesigner Designer;
private MethodInfo RefreshMethod;
private MethodInfo OnSelectionChangedMethod;
private TextBlock SelectionTypeLabel;
privateobject TheSelectedObject =null;
#endregion

#region Public properties
///<summary>
/// Get or sets the selected object. Can be null.
///</summary>
publicobject SelectedObject
{
get
{
returnthis.TheSelectedObject;
}
set
{
this.TheSelectedObject = value;

if (value !=null)
{
var context 
=new EditingContext();
var mtm 
=new ModelTreeManager(context);
mtm.Load(value);
var selection 
= Selection.Select(context, mtm.Root);

OnSelectionChangedMethod.Invoke(Designer.PropertyInspectorView, 
newobject[] { selection });
this.SelectionTypeLabel.Text = value.GetType().Name;
}
else
{
OnSelectionChangedMethod.Invoke(Designer.PropertyInspectorView, 
newobject[] { null });
this.SelectionTypeLabel.Text =string.Empty;
}
}
}

///<summary>
/// XAML information with PropertyGrid's font and color information
///</summary>
///<seealso>Documentation for WorkflowDesigner.PropertyInspectorFontAndColorData</seealso>
publicstring FontAndColorData
{
set 

Designer.PropertyInspectorFontAndColorData 
= value; 
}
}
#endregion

///<summary>
/// Default constructor, creates a hidden designer view and a property inspector
///</summary>
public WpfPropertyGrid()
{
this.Designer =new WorkflowDesigner();

var inspector 
= Designer.PropertyInspectorView;
Type inspectorType 
= inspector.GetType();

inspector.Visibility 
= Visibility.Visible;
this.Children.Add(inspector);

var methods 
= inspectorType.GetMethods(Reflection.BindingFlags.Public | Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance |
Reflection.BindingFlags.DeclaredOnly);

this.RefreshMethod = inspectorType.GetMethod("RefreshPropertyList",
Reflection.BindingFlags.NonPublic 
| Reflection.BindingFlags.Instance | Reflection.BindingFlags.DeclaredOnly);
this.OnSelectionChangedMethod = inspectorType.GetMethod("OnSelectionChanged"
Reflection.BindingFlags.Public 
| Reflection.BindingFlags.Instance | Reflection.BindingFlags.DeclaredOnly);
this.SelectionTypeLabel = inspectorType.GetMethod("get_SelectionTypeLabel",
Reflection.BindingFlags.Public 
| Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance |
Reflection.BindingFlags.DeclaredOnly).Invoke(inspector, 
newobject[0]) as TextBlock;

this.SelectionTypeLabel.Text =string.Empty;
}

///<summary>
/// Updates the PropertyGrid's properties
///</summary>
publicvoid RefreshPropertyList()
{
RefreshMethod.Invoke(Designer.PropertyInspectorView, 
newobject[] { false });
}
}
}
WPF中实现PropertyGrid的三种方式

效果:

WPF中实现PropertyGrid的三种方式

总结:本文提供了三种方式去在WPF中实现PropertyGrid。 





本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/archive/2010/09/02/Wpf-PropertyGrid-Demo.html,如需转载请自行联系原作者