由于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
说明:转载主要为了学习,怕以后找不到链接,所以就直接Copy上了,没有它意!