转:WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式

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

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

可以通过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控件。

1 <WindowsFormsHost Height="287" HorizontalAlignment="Left" Margin="18,12,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="200">            
2 
3     <my:PropertyGrid x:Name="PropertyGrid1"></my:PropertyGrid>         
4 
5 </WindowsFormsHost>

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

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

 1 <Window x:Class="WPGDemoApp.Window1"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:wpg="clr-namespace:WPG;assembly=WPG"
 5         Title="Window1" Height="300" Width="300">
 6     <DockPanel VerticalAlignment="Stretch" >
 7         <Button DockPanel.Dock="Top" x:Name="btn">button for test</Button>
 8         <wpg:PropertyGrid  DockPanel.Dock="Top" Instance="{Binding ElementName=btn}"  VerticalAlignment="Stretch" IsEnabled="True"></wpg:PropertyGrid>
 9     </DockPanel>
10 </Window>

第三种方式:使用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选择对象的改变。

  1 using System.Activities.Presentation; 
  2 
  3 using System.Activities.Presentation.Model; 
  4 
  5 using System.Activities.Presentation.View; 
  6 
  7 using System.Reflection; using System.Windows.Controls;
  8 
  9 namespace System.Windows.Control {     
 10 
 11 /// <summary>     
 12 
 13 /// WPF Native PropertyGrid class, taken from Workflow Foundation Designer     
 14 
 15 /// </summary>    
 16 
 17  public class WpfPropertyGrid : Grid     
 18 
 19 {         
 20 
 21 #region Private fields        
 22 
 23  private WorkflowDesigner Designer;        
 24 
 25  private MethodInfo RefreshMethod;         
 26 
 27 private MethodInfo OnSelectionChangedMethod;         
 28 
 29 private TextBlock SelectionTypeLabel;         
 30 
 31 private object TheSelectedObject = null;         
 32 
 33 #endregion
 34 
 35 #region Public properties        
 36 
 37  /// <summary>         
 38 
 39 /// Get or sets the selected object. Can be null.         
 40 
 41 /// </summary>         
 42 
 43 public object SelectedObject         
 44 
 45 {             
 46 
 47 get             
 48 
 49 { return this.TheSelectedObject;}             
 50 
 51 set{this.TheSelectedObject = value;        
 52 
 53 if (value != null)                 
 54 
 55 {                     
 56 
 57 var context = new EditingContext();                     
 58 
 59 var mtm = new ModelTreeManager(context);                     
 60 
 61 mtm.Load(value);                     
 62 
 63 var selection = Selection.Select(context, mtm.Root);
 64 
 65 OnSelectionChangedMethod.Invoke(Designer.PropertyInspectorView, new object[] { selection });                     
 66 
 67 this.SelectionTypeLabel.Text = value.GetType().Name;                 
 68 
 69 }                
 70 
 71  else                 
 72 
 73 {                    
 74 
 75  OnSelectionChangedMethod.Invoke(Designer.PropertyInspectorView, new object[] { null });                    
 76 
 77  this.SelectionTypeLabel.Text = string.Empty;                 
 78 
 79 }             
 80 
 81 }         
 82 
 83 }
 84 
 85 /// <summary>         
 86 
 87 /// XAML information with PropertyGrid's font and color information         
 88 
 89 /// </summary>         
 90 
 91 /// <seealso>Documentation for WorkflowDesigner.PropertyInspectorFontAndColorData</seealso>         
 92 
 93 public string FontAndColorData         
 94 
 95 {             
 96 
 97 set             
 98 
 99 {                
100 
101  Designer.PropertyInspectorFontAndColorData = value;             
102 
103 }         
104 
105 }         
106 
107 #endregion
108 
109 /// <summary>         
110 
111 /// Default constructor, creates a hidden designer view and a property inspector         
112 
113 /// </summary>         
114 
115 public WpfPropertyGrid()         
116 
117 {             
118 
119 this.Designer = new WorkflowDesigner();
120 
121 var inspector = Designer.PropertyInspectorView;             
122 
123 Type inspectorType = inspector.GetType();                         
124 
125 inspector.Visibility = Visibility.Visible;             
126 
127 this.Children.Add(inspector);
128 
129             
130 
131 var methods = inspectorType.GetMethods(
132 
133 Reflection.BindingFlags.Public | 
134 
135 Reflection.BindingFlags.NonPublic | 
136 
137 Reflection.BindingFlags.Instance |                 
138 
139 Reflection.BindingFlags.DeclaredOnly);
140 
141  this.RefreshMethod = inspectorType.GetMethod("RefreshPropertyList",                 
142 
143 Reflection.BindingFlags.NonPublic | 
144 
145 Reflection.BindingFlags.Instance | 
146 
147 Reflection.BindingFlags.DeclaredOnly);             
148 
149 this.OnSelectionChangedMethod = inspectorType.GetMethod("OnSelectionChanged",                 
150 
151 Reflection.BindingFlags.Public | 
152 
153 Reflection.BindingFlags.Instance | 
154 
155 Reflection.BindingFlags.DeclaredOnly);             
156 
157 this.SelectionTypeLabel = inspectorType.GetMethod("get_SelectionTypeLabel",                
158 
159  Reflection.BindingFlags.Public | 
160 
161 Reflection.BindingFlags.NonPublic | 
162 
163 Reflection.BindingFlags.Instance |
164 
165 Reflection.BindingFlags.DeclaredOnly).Invoke(inspector, new object[0]) as TextBlock;
166 
167 this.SelectionTypeLabel.Text = string.Empty;         
168 
169 }
170 
171 /// <summary>        
172 
173  /// Updates the PropertyGrid's properties         
174 
175 /// </summary>         
176 
177 public void RefreshPropertyList()         
178 
179 {             
180 
181 RefreshMethod.Invoke(Designer.PropertyInspectorView, new object[] { false });         
182 
183 }     
184 
185 } 
186 
187 }

代码:https://files.cnblogs.com/zhuqil/WpfPropertyGrid_Demo.rar

出处:http://zhuqil.cnblogs.com

说明:转载主要为了学习,怕以后找不到链接,所以就直接Copy上了,没有它意!

原文地址:https://www.cnblogs.com/GeneralKING/p/WPF.html