Click here to Skip to main content
14,836,169 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I got initial help for propertygrid control from this link to launch and display sample data. My requirement is based on an event, i should change the property grid's SelectedObject value from its viewmodel.

My XAML contains Usercontrol which has Extended wpf toolkit's PropertyGrid

C#
<usercontrol x:class="Helper.View.PropertyGridUserControl" xmlns:x="#unknown">
        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:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        xmlns:vm="clr-namespace:Helper.ViewModel"
        DataContext="{DynamicResource PropertyGridViewModel}"
        mc:Ignorable="d"
       xmlns:local="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit" >

    <Usercontrol.resources>
        <vm:propertygridviewmodel x:key="PropertyGridViewModel" xmlns:vm="#unknown" />
    </Usercontrol.resources>

    <Grid>
     <xctk:PropertyGrid x:Name="_propertyGrid" Margin="10" SelectedObject="{Binding PropertyGridData}"    AutoGenerateProperties="False">
           <!-- Only the following properties will be displayed in the PropertyGrid -->
         <xctk:PropertyGrid.PropertyDefinitions>
               <xctk:PropertyDefinition Name="CodeBookName"/>
               <xctk:PropertyDefinition Name="FavoriteColor"/>
               <xctk:PropertyDefinition Name="PetNames"/>
           </xctk:PropertyGrid.PropertyDefinitions>

       </xctk:PropertyGrid>


  </Grid>


and my ViewModel "PropertyGridViewModel" is

C#
public class PropertyGridViewModel : ViewModelBase
{
    PropertyGrid _propertyGrid;

    public PropertyGrid PropertyGridData 
    {
        get { return _propertyGrid; }
        set 
        { 
            _propertyGrid = value;
            OnPropertyChanged("PropertyGridData");
        } 
    }

    public PropertyGridViewModel()
    {
        CodeBookViewModel vm = new CodeBookViewModel();
        PropertyGridData = new PropertyGrid();
        PropertyGridData.PropertyDefinitions = new PropertyDefinitionCollection();
        PropertyDefinition item = new PropertyDefinition();
        string[] properties = { "CodeBookName", "CodeBookID" };
        item.TargetProperties = properties;
        PropertyGridData.PropertyDefinitions.Add(item);
        PropertyGridData.SelectedObject = vm;
    }
}

When I run this code, it is not showing any properties in PropertyGrid. If I have the same code in .CS file, I am able to see CodeBookName property, as this property is available in CodeBookViewModel.

Am I doing anything wrong here?

Based on the event, I will change the SelectedObject to another ViewModel here with different properties. Is it possible? Do I have to have all viewmodel's properties in XAML? or Can I generate on the fly from ViewModels by creating properties?

Please help me. Thanks in advance. Hope I have explained my question properly.
Posted
Updated 25-Mar-14 22:20pm
v3

1 solution

Hi Snprani,

Please look on similar question that I've answered:

Property Grid Binding in MVVM Architecture[^]

Now, you only need change the View-Modle (i.e. SelectedObject) by code.

Best Regards,

Shai
   
Comments
snprani 8-May-14 3:14am
   
Hi Shai,

Thanks for your response. Here is my XAML for property grid <br>
<pre lang="c#"><xctk:propertygrid x:name="_propertyGrid" margin="10" selectedobject="{Binding}" autogenerateproperties="False">
</xctk:propertygrid></pre>

Here is .CS file
public PropertyGridUserControl()
{
InitializeComponent();
Mediator.Instance.Register(
//Callback delegate, when message is seen
(Object o) =
{
UpdatePropertyGrid((TreeViewItemViewModel)o);
}, ViewModelMessages.PropertyChange);
}

void UpdatePropertyGrid(TreeViewItemViewModel selectedItem)
{
if (selectedItem is CodeBookViewModel)
{
this.DataContext = (CodeBookViewModel)selectedItem;
}
else if(selectedItem is DocumentEntityViewModel)
{
this.DataContext = (DocumentEntityViewModel)selectedItem;
}
}

This is what i have done in the code. Still it is not showing any data in the UI.

If I add propertydefinitins for each and every view model for the grid, it is showing data.

Please help in getting into dynamically changing the viewmodel based on treeview selection.
Shai Vashdi 10-May-14 17:27pm
   
When you are using an automatic properties you need to use Property Definitions:
[Category("Information")]
[DisplayName("First Name")]
[Description("This property uses a TextBox as the default editor.")]
Otherwise, you would have to build a mechanism based on reflection which is more complicated...
snprani 12-May-14 2:51am
   
Hi Shai,

Here is the snap of my ViewModel which contains automatic properties. Hope this is correct way of adding properties. If not please let me know how.
public class FieldEntityViewModel :TreeViewItemViewModel
{
FieldEntity _fieldEntity;

public FieldEntityViewModel(FieldEntity fieldEntity, DocumentEntityViewModel parentDocument)
: base(parentDocument)
{
Mediator.Instance.Register(
(Object o) => { RubberbandSizeChanged((Rect)o); }, ViewModelMessages.RubberbandSizeChanged);
_fieldEntity = fieldEntity;

}
[Category("Settings")]
[DisplayName("Field Name")]
[Description("Field Name")]
public string FieldName
{
get { return _fieldEntity.FieldName; }
set
{
_fieldEntity.FieldName = value;
OnPropertyChanged("FieldName");
}
}

[Category("Settings")]
[DisplayName("Field Type")]
[Description("Is it ICR, OCR or Activity type")]
public FieldType FieldType
{
get { return _fieldEntity.FieldType; }
set
{
_fieldEntity.FieldType = value;
OnPropertyChanged("FieldType");
}
}
[Category("Location & Size")]
[DisplayName("X Position")]
[Description("X Position of the rubberband region")]
public double X
{
get { return Math.Round(_fieldEntity.X); }
set
{
_fieldEntity.X = value;
OnPropertyChanged("X");
}
}
[Category("Location & Size")]
[DisplayName("Y Position")]
[Description("Y Position of the rubberband region")]
public double Y
{
get { return Math.Round(_fieldEntity.Y); }
set
{
_fieldEntity.Y = value;
OnPropertyChanged("Y");
}
}
[Category("Location & Size")]
[DisplayName("Width")]
[Description("Width of rubberband rectangle area")]
public double Width
{
get { return Math.Round(_fieldEntity.Width); }
set
{
_fieldEntity.Width = value;
OnPropertyChanged("Width");
}
}
[Category("Location & Size")]
[DisplayName("Height")]
[Description("Height of rubberband rectangle area")]
public double Height
{
get { return Math.Round(_fieldEntity.Height); }
set
{
_fieldEntity.Height = value;
OnPropertyChanged("Height");
}
}
}
Shai Vashdi 12-May-14 3:36am
   
Hi Snprani,

I've checked some of your code and for me it works fine.

public class FieldEntityViewModel
{

public FieldEntityViewModel()
{

}

FieldEntity _fieldEntity = new FieldEntity();


[Category("Settings")]
[DisplayName("Field Name")]
[Description("Field Name")]
public string FieldName
{
get { return _fieldEntity.FieldName; }
set
{
_fieldEntity.FieldName = value;
}
}

[Category("Location & Size")]
[DisplayName("X Position")]
[Description("X Position of the rubberband region")]
public double X
{
get { return Math.Round(_fieldEntity.X); }
set
{
_fieldEntity.X = value;

}
}
[Category("Location & Size")]
[DisplayName("Y Position")]
[Description("Y Position of the rubberband region")]
public double Y
{
get { return Math.Round(_fieldEntity.Y); }
set
{
_fieldEntity.Y = value;

}
}
[Category("Location & Size")]
[DisplayName("Width")]
[Description("Width of rubberband rectangle area")]
public double Width
{
get { return Math.Round(_fieldEntity.Width); }
set
{
_fieldEntity.Width = value;

}
}
[Category("Location & Size")]
[DisplayName("Height")]
[Description("Height of rubberband rectangle area")]
public double Height
{
get { return Math.Round(_fieldEntity.Height); }
set
{
_fieldEntity.Height = value;

}
}
}

I can't understand, what is the problem?
snprani 15-May-14 5:02am
   
I am not able to see properties in PropertyGrid with the code I have shared. Automatic properties are not working for me. Please help me.
I tried to create propertydefinitions directly from .cs file then i can see the properties.
Shai Vashdi 15-May-14 9:54am
   
The last example that I've wrote above, is working?
snprani 16-May-14 1:34am
   
Your solution is working perfectly. In my application, i have to change the DataContext based on TreeView. There it is not showing any data in the property grid.
Shai Vashdi 16-May-14 4:54am
   
Hi Snprani,

Thank you. The example I've wrote is based on most of the code you wrote above. Clearly the problem is related to the code of the TreeView. Please share the code.
snprani 16-May-14 6:58am
   
I have to change the DataContext based on a node selected in the treview. Parent node contains CodeBookViewModel, 2nd level contains DocumentViewModel like that i have 4 levels altogether.

I will paste the code for Propertygrid usercontrol. The main window contains this usercontrol in it. By default this usercontrol is getting the MainViewModel as its DataContext(nothing assinged but parent datacontext is received by all child controls). On selection of node in treeview, using Messenger , i am telling propertygrid to change its DataContext by passing appropriate object for it.

Here is the code. I am unable to share the files directly so copy pasting the code here.

PropertyGridUserControl.xaml.cs
public partial class PropertyGridUserControl : UserControl
{
string[] codeBookProperties = { "CodeBookName", "CodeBookDescription", "TemplateImageFolder" };
string[] docSetProperties = { "DocSetName", "DocSetDescription", "OriginalImagePath" };
string[] fieldProperties = { "DisplayName", "FieldName", "FieldType", "X", "Y", "Width", "Height", "SubFieldAvailable", "LexiconText", "RegexFileName", "SelectedDataType","DataTypes" };
string[] subFieldProperties = { "SubFieldName", "FieldType", "X", "Y", "Width", "Height", "SelectedDataType", "DataTypes" };

public PropertyGridUserControl()
{
InitializeComponent();

Mediator.Instance.Register(
//Callback delegate, when message is seen
(Object o) =>
{
UpdatePropertyGrid((TreeViewItemViewModel)o);
}, ViewModelMessages.PropertyChange);

_propertyGrid.PropertyDefinitions = new PropertyDefinitionCollection();
}

void GetPropertyItem(string[] Properties)
{
PropertyDefinition item = new PropertyDefinition();
item.TargetProperties = Properties;

_propertyGrid.PropertyDefinitions.Add(item);
}

///
/// Change the propertygrid elements based on Treeview selected item.
///

/// <param name="selectedItem"></param>
void UpdatePropertyGrid(TreeViewItemViewModel selectedItem)
{
if (selectedItem is CodeBookViewModel)
{
// this.DataContext = (CodeBookViewModel)selectedItem;

GetPropertyItem(codeBookProperties);
_propertyGrid.SelectedObject = selectedItem;
}
else if (selectedItem is DocumentEntityViewModel)
{
//this.DataContext = (DocumentEntityViewModel)selectedItem;

GetPropertyItem(docSetProperties);
_propertyGrid.SelectedObject = selectedItem;
}
else if (selectedItem is FieldEntityViewModel)
{
//this.DataContext = (FieldEntityViewModel)selectedItem;

GetPropertyItem(fieldProperties);
_propertyGrid.SelectedObject = selectedItem;
((FieldEntityViewModel)selectedItem).DataTypes = XMLOperation.GetDataTypes();

}
else if (selectedItem is SubFieldEntityViewModel)
{
//this.DataContext = (SubFieldEntityViewModel)selectedItem;

GetPropertyItem(subFieldProperties);
_propertyGrid.SelectedObject = selectedItem;
}
}
}

PropertyGridUserControl.xaml
<grid>
<xctk:propertygrid x:name="_propertyGrid" margin="10" selectedobject="{Binding}"
="" autogenerateproperties="False">



Hope this gives you clear idea, what i am trying to explain. Let me know otherwise. Thanks for your replies.
Shai Vashdi 16-May-14 7:14am
   
Are you sure that the method UpdatePropertyGrid is being called? Please put a break point there to verify...
snprani 19-May-14 8:23am
   
Yes. That is been called, and i am able to see the Properties as i have added propertydefinitions in the same method. Automatic properties are not working though.
Shai Vashdi 19-May-14 8:49am
   
I still don't understand... please clarify.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900