title: How to get the non public property of an object and its value at the same time
body: <p>How to get all non  public properties of an object and its value at the same time so that the object can be given to a property grid at run time to populate its values.</p>
  
  <p>the scenario is like this whenever treeviewitem of TreeView is selected, propertygrid is changed automatically as selection changes in treeview.</p>
  
  <p>here is the xaml file.</p>
  
  <pre><code>&lt;UserControl x:Class="WpfExperiment.AdditionalProperty"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
               xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
               xmlns:sys="clr-namespace:System;assembly=mscorlib"
                 xmlns:wpg="clr-namespace:System.Windows.Controls"
  
              &gt;
  
      &lt;UserControl.Resources&gt;
              &lt;DataTemplate DataType="{x:Type sys:String}" x:Key="RadioButtons"&gt;
                  &lt;RadioButton Margin="0,3" Content="{Binding .}" GroupName="radios" Checked="Item_Checked" /&gt;
              &lt;/DataTemplate&gt;
              &lt;ObjectDataProvider x:Key="SortTypes" MethodName="GetValues" ObjectType="{x:Type sys:Enum}"&gt;
                  &lt;ObjectDataProvider.MethodParameters&gt;
                      &lt;x:Type TypeName="wpg:PropertySort"/&gt;
                  &lt;/ObjectDataProvider.MethodParameters&gt;
              &lt;/ObjectDataProvider&gt;
  
  
      &lt;/UserControl.Resources&gt;
      &lt;Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"&gt;
  
  
          &lt;wpg:WpfPropertyGrid  x:Name="PropertyGrid1" 
              Margin="20,20,118,21" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
              HelpVisible="{Binding ElementName=ShowDescrip, Path=IsChecked}" 
              ToolbarVisible="{Binding ElementName=ShowToolbar, Path=IsChecked}"
              PropertySort="{Binding ElementName=ComboSort, Path=SelectedItem}" /&gt;
          &lt;StackPanel Orientation="Vertical"   HorizontalAlignment="Right" VerticalAlignment="Top"&gt;
              &lt;TextBlock Margin="0,0,0,10" &gt;Selected Object:&lt;/TextBlock&gt;
             &lt;ItemsControl x:Name="ItemList" ItemTemplate="{StaticResource RadioButtons}" Height="100" Visibility="{Binding }" /&gt;
              &lt;TextBlock Margin="0,10,0,3" &gt;Selection Type:&lt;/TextBlock&gt;
  
              &lt;TextBlock Margin="0,10,0,3" &gt;Features:&lt;/TextBlock&gt;
              &lt;CheckBox Name="ShowDescrip" Margin="0,3,0,3" Content="Help Visible" /&gt;
              &lt;CheckBox Name="ShowToolbar" Margin="0,3,0,3" IsChecked="True" Content="Toolbar Visible" /&gt;
              &lt;ComboBox Name="ComboSort" Margin="0,3,0,0" Width="95" FontSize="10"
                  SelectedIndex="0" ItemsSource="{Binding Source={StaticResource SortTypes}}" /&gt;
          &lt;/StackPanel&gt;
  
  
  
      &lt;/Grid&gt;
  
  &lt;/UserControl&gt;
  </code></pre>
  
  <p>AdditionalProperty.xaml.cs</p>
  
  <pre><code> /// &lt;summary&gt;
      /// Interaction logic for AdditionalProperty.xaml
      /// &lt;/summary&gt;
      public partial class AdditionalProperty : UserControl
      {
          static private Person Person;
  
          public AdditionalProperty(Person _person)
          {
              Person = _person;
          }
  
          // names must match the data members
          private object[] ItemArray = { "Person" };
          public AdditionalProperty()
          {
                  InitializeComponent();
                  this.ItemList.ItemTemplate = this.Resources["RadioButtons"] as DataTemplate;
                  this.ItemList.ItemsSource = this.ItemArray;
  
          }
  
  
          private void Item_Checked(object sender, RoutedEventArgs e)
          {
  
              if (e.Source is RadioButton)
              {
  
                  object selected = this.GetType().GetField("Person",   System.Reflection.BindingFlags.NonPublic).GetValue(this);
  
                 this. PropertyGrid1.SelectedObject = selected;
  
  
  
  
              }
          }
  
  
  
      }
  }
  </code></pre>
  
  <p>this usercontrol is embedded in a window control like this.</p>
  
  <pre><code>&lt;Window x:Class="WpfExperiment.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:sys="clr-namespace:System;assembly=mscorlib"
              xmlns:wpg="clr-namespace:System.Windows.Controls"
          xmlns:local="clr-namespace:WpfExperiment"
          Title="MainWindow" Height="350" Width="525"&gt;
  
   &lt;local:AdditionalProperty Grid.Column="1"  /&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>MainWindow.xaml.cs</p>
  
  <pre><code>public partial class MainWindow : Window
      {
         private Person Person = new Person("Shakti");
         // names must match the data members
         private object[] ItemArray = { "Person"};
  
          public MainWindow()
          {
              InitializeComponent();
                new AdditionalProperty(Person);
  
          }
  }
  </code></pre>
  
  <p>WpfPropertyGrid code:</p>
  
  <pre><code>namespace System.Windows.Controls
  {
      public enum PropertySort
      {
          NoSort = 0,
          Alphabetical = 1,
          Categorized = 2,
          CategorizedAlphabetical = 3
      }; 
      /// &lt;summary&gt;WPF Native PropertyGrid class, uses Workflow Foundation's PropertyInspector&lt;/summary&gt;
      public class WpfPropertyGrid : Grid
      {
          #region Private fields
          private WorkflowDesigner Designer;
          private MethodInfo RefreshMethod;
          private MethodInfo OnSelectionChangedMethod;
          private MethodInfo IsInAlphaViewMethod;
          private TextBlock SelectionTypeLabel;
          private Control PropertyToolBar;
          private Border HelpText;
          private GridSplitter Splitter;
          private double HelpTextHeight = 60;
          #endregion
  
          #region Public properties
          /// &lt;summary&gt;Get or sets the selected object. Can be null.&lt;/summary&gt;
          public object SelectedObject
          {
              get { return GetValue(SelectedObjectProperty); }
              set { SetValue(SelectedObjectProperty, value); }
          }
          /// &lt;summary&gt;Get or sets the selected object collection. Returns empty array by default.&lt;/summary&gt;
          public object[] SelectedObjects
          {
              get { return GetValue(SelectedObjectsProperty) as object[]; }
              set { SetValue(SelectedObjectsProperty, value); }
          }
          /// &lt;summary&gt;XAML information with PropertyGrid's font and color information&lt;/summary&gt;
          /// &lt;seealso&gt;Documentation for WorkflowDesigner.PropertyInspectorFontAndColorData&lt;/seealso&gt;
          public string FontAndColorData
          {
              set
              {
                  Designer.PropertyInspectorFontAndColorData = value;
              }
          }
          /// &lt;summary&gt;Shows the description area on the top of the control&lt;/summary&gt;
          public bool HelpVisible
          {
              get { return (bool)GetValue(HelpVisibleProperty); }
              set { SetValue(HelpVisibleProperty, value); }
          }
          /// &lt;summary&gt;Shows the tolbar on the top of the control&lt;/summary&gt;
          public bool ToolbarVisible
          {
              get { return (bool)GetValue(ToolbarVisibleProperty); }
              set { SetValue(ToolbarVisibleProperty, value); }
          }
          public PropertySort PropertySort
          {
              get { return (PropertySort)GetValue(PropertySortProperty); }
              set { SetValue(PropertySortProperty, value); }
          }
          #endregion
  
          #region Dependency properties registration
          public static readonly DependencyProperty SelectedObjectProperty =
              DependencyProperty.Register("SelectedObject", typeof(object), typeof(WpfPropertyGrid),
              new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, SelectedObjectPropertyChanged));
  
          public static readonly DependencyProperty SelectedObjectsProperty =
              DependencyProperty.Register("SelectedObjects", typeof(object[]), typeof(WpfPropertyGrid),
              new FrameworkPropertyMetadata(new object[0], FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, SelectedObjectsPropertyChanged, CoerceSelectedObjects));
  
          public static readonly DependencyProperty HelpVisibleProperty =
              DependencyProperty.Register("HelpVisible", typeof(bool), typeof(WpfPropertyGrid),
              new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, HelpVisiblePropertyChanged));
          public static readonly DependencyProperty ToolbarVisibleProperty =
              DependencyProperty.Register("ToolbarVisible", typeof(bool), typeof(WpfPropertyGrid),
              new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ToolbarVisiblePropertyChanged));
          public static readonly DependencyProperty PropertySortProperty =
              DependencyProperty.Register("PropertySort", typeof(PropertySort), typeof(WpfPropertyGrid),
              new FrameworkPropertyMetadata(PropertySort.CategorizedAlphabetical, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PropertySortPropertyChanged));
          #endregion
  
          #region Dependency properties events
          private static object CoerceSelectedObject(DependencyObject d, object value)
          {
              WpfPropertyGrid pg = d as WpfPropertyGrid;
  
              object[] collection = pg.GetValue(SelectedObjectsProperty) as object[];
  
              return collection.Length == 0 ? null : value;
          }
          private static object CoerceSelectedObjects(DependencyObject d, object value)
          {
              WpfPropertyGrid pg = d as WpfPropertyGrid;
  
              object single = pg.GetValue(SelectedObjectsProperty);
  
              return single == null ? new object[0] : value;
          }
  
          private static void SelectedObjectPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
          {
              WpfPropertyGrid pg = source as WpfPropertyGrid;
              pg.CoerceValue(SelectedObjectsProperty);
  
              if (e.NewValue == null)
              {
                  pg.OnSelectionChangedMethod.Invoke(pg.Designer.PropertyInspectorView, new object[] { null });
                  pg.SelectionTypeLabel.Text = string.Empty;
              }
              else
              {
                  var context = new EditingContext();
                  var mtm = new ModelTreeManager(context);
                  mtm.Load(e.NewValue);
                  Selection selection = Selection.Select(context, mtm.Root);
  
                  pg.OnSelectionChangedMethod.Invoke(pg.Designer.PropertyInspectorView, new object[] { selection });
                  pg.SelectionTypeLabel.Text = e.NewValue.GetType().Name;
              }
  
              pg.ChangeHelpText(string.Empty, string.Empty);
          }
          private static void SelectedObjectsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
          {
              WpfPropertyGrid pg = source as WpfPropertyGrid;
              pg.CoerceValue(SelectedObjectsProperty);
  
              object[] collection = e.NewValue as object[];
  
              if (collection.Length == 0)
              {
                  pg.OnSelectionChangedMethod.Invoke(pg.Designer.PropertyInspectorView, new object[] { null });
                  pg.SelectionTypeLabel.Text = string.Empty;
              }
              else
              {
                  bool same = true;
                  Type first = null;
  
                  var context = new EditingContext();
                  var mtm = new ModelTreeManager(context);
                  Selection selection = null;
  
                  // Accumulates the selection and determines the type to be shown in the top of the PG
                  for (int i = 0; i &lt; collection.Length; i++)
                  {
                      mtm.Load(collection[i]);
                      if (i == 0)
                      {
                          selection = Selection.Select(context, mtm.Root);
                          first = collection[0].GetType();
                      }
                      else
                      {
                          selection = Selection.Union(context, mtm.Root);
                          if (!collection[i].GetType().Equals(first))
                              same = false;
                      }
                  }
  
                  pg.OnSelectionChangedMethod.Invoke(pg.Designer.PropertyInspectorView, new object[] { selection });
                  pg.SelectionTypeLabel.Text = same ? first.Name + " &lt;multiple&gt;" : "Object &lt;multiple&gt;";
              }
  
              pg.ChangeHelpText(string.Empty, string.Empty);
          }
          private static void HelpVisiblePropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
          {
              WpfPropertyGrid pg = source as WpfPropertyGrid;
  
              if (e.NewValue != e.OldValue)
              {
                  if (e.NewValue.Equals(true))
                  {
                      pg.RowDefinitions[1].Height = new GridLength(5);
                      pg.RowDefinitions[2].Height = new GridLength(pg.HelpTextHeight);
                  }
                  else
                  {
                      pg.HelpTextHeight = pg.RowDefinitions[2].Height.Value;
                      pg.RowDefinitions[1].Height = new GridLength(0);
                      pg.RowDefinitions[2].Height = new GridLength(0);
                  }
              }
          }
          private static void ToolbarVisiblePropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
          {
              WpfPropertyGrid pg = source as WpfPropertyGrid;
              pg.PropertyToolBar.Visibility = e.NewValue.Equals(true) ? Visibility.Visible : Visibility.Collapsed;
          }
          private static void PropertySortPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
          {
              WpfPropertyGrid pg = source as WpfPropertyGrid;
              PropertySort sort = (PropertySort)e.NewValue;
  
              bool isAlpha = (sort == PropertySort.Alphabetical || sort == PropertySort.NoSort);
              pg.IsInAlphaViewMethod.Invoke(pg.Designer.PropertyInspectorView, new object[] { isAlpha });
          }
          #endregion
  
          /// &lt;summary&gt;Default constructor, creates the UIElements including a PropertyInspector&lt;/summary&gt;
          public WpfPropertyGrid()
          {
              this.ColumnDefinitions.Add(new ColumnDefinition());
  
              this.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
              this.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(0) });
              this.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(0) });
  
              this.Designer = new WorkflowDesigner();
              TextBlock title = new TextBlock()
              {
                  Visibility = Windows.Visibility.Visible,
                  TextWrapping = TextWrapping.NoWrap,
                  TextTrimming = TextTrimming.CharacterEllipsis,
                  FontWeight = FontWeights.Bold
              };
              TextBlock descrip = new TextBlock()
              {
                  Visibility = Windows.Visibility.Visible,
                  TextWrapping = TextWrapping.Wrap,
                  TextTrimming = TextTrimming.CharacterEllipsis
              };
              DockPanel dock = new DockPanel()
              {
                  Visibility = Windows.Visibility.Visible,
                  LastChildFill = true,
                  Margin = new Thickness(3, 0, 3, 0)
              };
  
              title.SetValue(DockPanel.DockProperty, Dock.Top);
              dock.Children.Add(title);
              dock.Children.Add(descrip);
              this.HelpText = new Border()
              {
                  Visibility = Windows.Visibility.Visible,
                  BorderBrush = SystemColors.ActiveBorderBrush,
                  Background = SystemColors.ControlBrush,
                  BorderThickness = new Thickness(1),
                  Child = dock
              };
              this.Splitter = new GridSplitter()
              {
                  Visibility = Windows.Visibility.Visible,
                  ResizeDirection = GridResizeDirection.Rows,
                  Height = 5,
                  HorizontalAlignment = Windows.HorizontalAlignment.Stretch
              };
  
              var inspector = Designer.PropertyInspectorView;
              inspector.Visibility = Visibility.Visible;
              inspector.SetValue(FrameworkElement.VerticalAlignmentProperty, VerticalAlignment.Stretch);
  
              this.Splitter.SetValue(Grid.RowProperty, 1);
              this.Splitter.SetValue(Grid.ColumnProperty, 0);
  
              this.HelpText.SetValue(Grid.RowProperty, 2);
              this.HelpText.SetValue(Grid.ColumnProperty, 0);
  
              Binding binding = new Binding("Parent.Background");
              title.SetBinding(BackgroundProperty, binding);
              descrip.SetBinding(BackgroundProperty, binding);
  
              this.Children.Add(inspector);
              this.Children.Add(this.Splitter);
              this.Children.Add(this.HelpText);
  
              Type inspectorType = inspector.GetType();
              var props = inspectorType.GetProperties(Reflection.BindingFlags.Public | Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance |
                  Reflection.BindingFlags.DeclaredOnly);
  
              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.IsInAlphaViewMethod = inspectorType.GetMethod("set_IsInAlphaView",
                  Reflection.BindingFlags.Public | 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, new object[0]) as TextBlock;
              this.PropertyToolBar = inspectorType.GetMethod("get_PropertyToolBar",
                  Reflection.BindingFlags.Public | Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance |
                  Reflection.BindingFlags.DeclaredOnly).Invoke(inspector, new object[0]) as Control;
              inspectorType.GetEvent("GotFocus").AddEventHandler(this,
                  Delegate.CreateDelegate(typeof(RoutedEventHandler), this, "GotFocusHandler", false));
  
              this.SelectionTypeLabel.Text = string.Empty;
          }
          /// &lt;summary&gt;Updates the PropertyGrid's properties&lt;/summary&gt;
          public void RefreshPropertyList()
          {
              RefreshMethod.Invoke(Designer.PropertyInspectorView, new object[] { false });
          }
  
          /// &lt;summary&gt;Traps the change of focused property and updates the help text&lt;/summary&gt;
          /// &lt;param name="sender"&gt;Not used&lt;/param&gt;
          /// &lt;param name="args"&gt;Points to the source control containing the selected property&lt;/param&gt;
          private void GotFocusHandler(object sender, RoutedEventArgs args)
          {
              //if (args.OriginalSource is TextBlock)
              //{
              string title = string.Empty;
              string descrip = string.Empty;
              var theSelectedObjects = this.GetValue(SelectedObjectsProperty) as object[];
  
              if (theSelectedObjects != null &amp;&amp; theSelectedObjects.Length &gt; 0)
              {
                  Type first = theSelectedObjects[0].GetType();
                  for (int i = 1; i &lt; theSelectedObjects.Length; i++)
                  {
                      if (!theSelectedObjects[i].GetType().Equals(first))
                      {
                          ChangeHelpText(title, descrip);
                          return;
                      }
                  }
  
                  object data = (args.OriginalSource as FrameworkElement).DataContext;
                  PropertyInfo propEntry = data.GetType().GetProperty("PropertyEntry");
                  if (propEntry == null)
                  {
                      propEntry = data.GetType().GetProperty("ParentProperty");
                  }
  
                  if (propEntry != null)
                  {
                      object propEntryValue = propEntry.GetValue(data, null);
                      string propName = propEntryValue.GetType().GetProperty("PropertyName").GetValue(propEntryValue, null) as string;
                      title = propEntryValue.GetType().GetProperty("DisplayName").GetValue(propEntryValue, null) as string;
                      PropertyInfo property = theSelectedObjects[0].GetType().GetProperty(propName);
                      object[] attrs = property.GetCustomAttributes(typeof(DescriptionAttribute), true);
  
                      if (attrs != null &amp;&amp; attrs.Length &gt; 0)
                          descrip = (attrs[0] as DescriptionAttribute).Description;
                  }
                  ChangeHelpText(title, descrip);
              }
              //}
          }
          /// &lt;summary&gt;Changes the text help area contents&lt;/summary&gt;
          /// &lt;param name="title"&gt;Title in bold&lt;/param&gt;
          /// &lt;param name="descrip"&gt;Description with ellipsis&lt;/param&gt;
          private void ChangeHelpText(string title, string descrip)
          {
              DockPanel dock = this.HelpText.Child as DockPanel;
              (dock.Children[0] as TextBlock).Text = title;
              (dock.Children[1] as TextBlock).Text = descrip;
          }
      }
  }
  </code></pre>
  
  <p>Person class:</p>
  
  <pre><code>  public class Person
      {
          public enum Gender { Male, Female }
  
          #region private fields
          private string[] _Names = new string[3];
          #endregion
  
          // The following properties are wrapping an array of strings
          #region Public Properties
          [Category("Name")]
          [DisplayName("First Name")]
          public string FirstName
          {
              set { _Names[0] = value; }
              get { return _Names[0]; }
          }
  
          [Category("Name")]
          [DisplayName("Mid Name")]
          public string MidName
          {
              set { _Names[1] = value; }
              get { return _Names[1]; }
          }
  
          [Category("Name")]
          [DisplayName("Last Name")]
          public string LastName
          {
              set { _Names[2] = value; }
              get { return _Names[2]; }
          }
  
          // The following are autoimplemented properties (C# 3.0 and up)
          [Category("Characteristics")]
          [DisplayName("Gender")]
          public Gender PersonGender { get; set; }
  
          [Category("Characteristics")]
          [DisplayName("Birth Date")]
          public DateTime BirthDate { get; set; }
  
          [Category("Characteristics")]
          public int Income { get; set; }
  
          // Other cases of hidden read-only property and formatted property
          [DisplayName("GUID"), ReadOnly(true), Browsable(true)]   // many attributes defined in the same row
          public string GuidStr
          {
              get { return Guid.ToString(); }
          }
  
          [Browsable(false)]  // this property will not be displayed
          public System.Guid Guid
          {
              get;
              private set;
          }
          #endregion
  
          public Person(string name)
          {
              // default values
              for (int i = 0; i &lt; 3; i++)
                  _Names[i] = name;
              this.PersonGender = Gender.Male;
              this.Guid = System.Guid.NewGuid();
          }
  
          public override string ToString()
          {
              return string.Format("{0} {1} {2}", FirstName, MidName, LastName).Trim().Replace("  ", " ");
          }
      }
  </code></pre>
  
  <p>I am not able to understand why part of this code is returning null:</p>
  
  <pre><code>object selected = **this.GetType().GetField("Person",   System.Reflection.BindingFlags.NonPublic)**.GetValue(this);
  </code></pre>
  
  <p>just for reference this code has been adapted from [http://www.codeproject.com/Articles/87715/Native-WPF-4-PropertyGrid]</p>