I have made it to hide/show value column of a property individually, but does not make it work to show/hide the whole property row(not only the value column, but also the label column). What's more how to hide a whole group?
You are really appreciated if you could share some code. Thank you very much.
21 Answers, 1 is accepted
You may hide property definitions by removing them from the RadPropertyGrid.PropertyDefinitions collection.
Greetings,
Pavel Pavlov
the Telerik team
Thank you for the information. but I'm using the PropertyGrid control under MVVM, no MVVM framework introduced. Was that meaning that View Model should know the control instance.
Would you please share more information? As PropertyDefinition has no Visibility property which can be bound to show/hide it.
A visibility property for the PropertyDefinition type has been introduced with Q1 SP (2012.1 326). Would you please confirm whether it meets your requirements?
Greetings,
Ivan Ivanov
the Telerik team
That's great, thank your for the information. I will download the version and have a try.
With the binding to visibility property, the view model can control what properties to be shown.
I saw the Visibility property in PropertyDefinition, it works if I gave Collapsed to it(when the user control loaded), the third property definition is hidden.
But the second one which bound is not working, actually I did not see the bind source(Property0BindSource) in Visibility is called.
So my question is if the Visibility property support binding, orI have wrong usage.
Our requirement is to make the Visibility of a PropertyDefinition can be changed in program in MVVM.
Thank you very much.
<UserControl.Resources>
<Converter:BooleanToVisibility x:Key="converter" />
</UserControl.Resources><telerik:PropertyDefinition Binding="{Binding Property0BindSource}" GroupName="Group1" DisplayName="Property0" OrderIndex="100" />
<telerik:PropertyDefinition Binding="{Binding Property1BindSource}" GroupName="Group1" DisplayName="Property1" OrderIndex="101" Visibility="{Binding Property0BindSource, Converter={StaticResource converter}}"/>
<telerik:PropertyDefinition Binding="{Binding Property2BindSource1}" GroupName="Group1" DisplayName="Property2" OrderIndex="102" Visibility="Collapsed"/>
I believe that you have wrong DataContext for your PropertyDefinitions. Would you please try setting the binding like this:
<
telerik:RadPropertyGrid
x:Name
=
"rpg"
AutoGeneratePropertyDefinitions
=
"False"
>
<
telerik:RadPropertyGrid.PropertyDefinitions
>
<
telerik:PropertyDefinition
Binding
=
"{Binding StringProp}"
Visibility
=
"{Binding Item.VisProp, ElementName=rpg}"
/>
</
telerik:RadPropertyGrid.PropertyDefinitions
>
</
telerik:RadPropertyGrid
>
All the best,
Ivan Ivanov
the Telerik team
Hi Ivan,
Sorry for delayed response as I were out of office recently. I have tried as your suggestion. but still did not make it work
I'm wondering if you would look at my code and give me more instruction.
The WorkingExample.xaml and WorkingExampleViewModel.cs are the view and view model, which I can hide VisaNo property value column and Friend property value column according to IsChild and IsLicensed property in View Model. You could see that the visiblity property of a textbox is working with binding to a property in the view model, but I can not make it work on PropertyDefinition.
Our requirement for this sample code is that
1.) if IsChild is checked, hide VisaNo PropertyDefinition, otherwise show it
2.) if IsLicensed in ViewModel is true, show Friend PropertyDefinition, otherwise hide it.
As I can not upload the whole sample solution, so I just attached the view and view model
1. WorkingExample.xaml:
<Window x:Class="RadControlsWpfApp1.WorkingExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:Converter="clr-namespace:RadControlsWpfApp1" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Converter:BooleanToVisibility x:Key="converter" />
<Converter:DTSelector x:Key="dataTemplateSelector">
<!--<Converter:DTSelector.IsChildDataTemplate>
<DataTemplate>
<CheckBox x:Name="cbIsChild" BorderBrush="White" IsChecked="{Binding Path=IsChild}"/>
</DataTemplate>
</Converter:DTSelector.IsChildDataTemplate>-->
<Converter:DTSelector.VisaNoDataTemplate>
<DataTemplate>
<TextBox BorderBrush="White" Text="{Binding Path=VisaNo}" Visibility="{Binding Path =IsChild, Converter={StaticResource converter}}"/>
</DataTemplate>
</Converter:DTSelector.VisaNoDataTemplate>
<Converter:DTSelector.FriendDataTemplate>
<DataTemplate>
<TextBox BorderBrush="White" Text="{Binding Path=Friend}" Visibility="{Binding Path =IsLicensed, Converter={StaticResource converter}}"/>
</DataTemplate>
</Converter:DTSelector.FriendDataTemplate>
</Converter:DTSelector>
</Window.Resources>
<Grid>
<telerik:RadPropertyGrid x:Name="propertyGrid" Item="{Binding}" EditorTemplateSelector="{StaticResource dataTemplateSelector}"
LabelColumnWidth="100" AutoGeneratePropertyDefinitions="False" DescriptionPanelVisibility ="Collapsed" SortAndGroupButtonsVisibility="Visible"
IsGrouped="True"
Height="600" MaxHeight="600"
>
<telerik:RadPropertyGrid.PropertyDefinitions>
<!--General Group-->
<telerik:PropertyDefinition Binding="{Binding Name}" GroupName="General" DisplayName="Name" OrderIndex="0" />
<telerik:PropertyDefinition x:Name="IsChildProp" Binding="{Binding IsChild}" GroupName="General" DisplayName="Is Child" OrderIndex="1" />
<!-- the below visibility setting is not working -->
<telerik:PropertyDefinition Binding="{Binding VisaNo}" GroupName="General" DisplayName="VisaNo" OrderIndex="2" Visibility="{Binding Path=IsChild, Converter={StaticResource converter}}" />
<!--<telerik:PropertyDefinition Binding="{Binding VisaNo}" GroupName="General" DisplayName="VisaNo" OrderIndex="2" Visibility="{Binding IsChecked, ElementName=cbIsChild, Converter={StaticResource converter}}" />-->
<telerik:PropertyDefinition Binding="{Binding Friend}" GroupName="General" DisplayName="Best Friend" OrderIndex="3" />
</telerik:RadPropertyGrid.PropertyDefinitions>
</telerik:RadPropertyGrid>
</Grid>
</Window>
2. WorkingExampleViewModel.cs:
public class WorkingExampleViewModel: INotifyPropertyChanged, IDataErrorInfo
{
public WorkingExampleViewModel()
{
CurrentPeople = new People {Name = "Peter", IsChild = false, Friend = "John", VisaNo = "G1520110"};
//remove below setting, the friend value will be hide
//if is not licensed, hide friend property
IsLicensed = true;
}
private string _name;
public string Name
{
get { return CurrentPeople.Name; }
set
{
if (_name == value) return;
_name = value;
CurrentPeople.Name = value;
OnPropertyChanged("Name");
}
}
private bool _isChild;
public bool IsChild
{
get { return CurrentPeople.IsChild; }
set
{
if (_isChild == value) return;
_isChild = value;
CurrentPeople.IsChild = value;
OnPropertyChanged("IsChild");
}
}
private string _friend;
public string Friend
{
get { return CurrentPeople.Friend; }
set
{
if (_friend == value) return;
_friend = value;
CurrentPeople.Friend = value;
OnPropertyChanged("Friend");
}
}
private string _visaNo;
public string VisaNo
{
get { return CurrentPeople.VisaNo; }
set
{
if (_visaNo == value) return;
_visaNo = value;
CurrentPeople.VisaNo = value;
OnPropertyChanged("VisaNo");
}
}
private People _currentPeople;
public People CurrentPeople
{
get { return _currentPeople; }
set
{
if (_currentPeople == value) return;
_currentPeople = value;
OnPropertyChanged("CurrentPeople");
}
}
private bool _isLicensed = false;
public bool IsLicensed
{
get { return _isLicensed; }
set
{
if (_isLicensed == value) return;
_isLicensed = value;
OnPropertyChanged("IsLicensed");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
3. app.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// only can hide value column using DataTemplate Selector
// we would like to make it if IsChild unchecked, hide whole propertydefinition of VisaNo
// if IsLicensed = false, hiden whole propertydefinition of Friend
var window = new WorkingExample();
var viewModel = new WorkingExampleViewModel();
window.DataContext = viewModel;
window.Show();
}
I guess it's something related wrong usage, but not sure how to correct them.
Thank you very much.
On the one hand PropertyDefiniton is DependencyObject, but on the other hand PropertyDefinitons are not included in the visual tree (they just serve as view models for their respective PropertyGridFields), so that they support binding, but they cannot be bound with ElementName source. In order to achive this you might try using a property in your view model to which both PropertyDefinition and CheckBox are bound.
Greetings,
Ivan Ivanov
the Telerik team
Sorry I did not catch your point completely, in my sample code, IsChild is the property in ViewModel which is bound to both PropertyDefinition and CheckBox, but the PropertyDefinition was not working.
The data template selector I used in sample code is to check that the property IsChild can be bound to visiblity of a text box, so that if IsChild changed to false, the textbox can be hidden, this is the workaround as it can only hide PropertyDefinition value column, not whole property definition. Actually this is not the perfect one.
<!-- IsChild is bound to Visibility and it's hidden once IsChild is false -- >
<Converter:DTSelector.VisaNoDataTemplate>
<DataTemplate>
<TextBox BorderBrush="White" Text="{Binding Path=VisaNo}" Visibility="{Binding Path =IsChild, Converter={StaticResource converter}}"/>
</DataTemplate>
</Converter:DTSelector.VisaNoDataTemplate>
What I expected is that if PropertyDefinition Visibility supports full binding, the below code(in BOLD) should be working, but as I mentioned before, actually it does not work.
if I can not make it work with any solution via Binding to visibility of PropertyDefinition(could you give me some code which can work), then I guess we have to turn to code behind to remove propertydefintion(to be hiden) from PropertyDefinitions.
<telerik:RadPropertyGrid x:Name="propertyGrid" Item="{Binding}" EditorTemplateSelector="{StaticResource dataTemplateSelector}"
LabelColumnWidth="100" AutoGeneratePropertyDefinitions="False" DescriptionPanelVisibility ="Collapsed" SortAndGroupButtonsVisibility="Visible"
IsGrouped="True"
Height="600" MaxHeight="600"
>
<telerik:RadPropertyGrid.PropertyDefinitions>
<!--General Group-->
<telerik:PropertyDefinition Binding="{Binding Name}" GroupName="General" DisplayName="Name" OrderIndex="0" />
<telerik:PropertyDefinition x:Name="IsChildProp" Binding="{Binding IsChild}" GroupName="General" DisplayName="Is Child" OrderIndex="1" />
<telerik:PropertyDefinition Binding="{Binding VisaNo}" GroupName="General" DisplayName="VisaNo" OrderIndex="2" Visibility="{Binding Path=IsChild, Converter={StaticResource converter}}" />
<telerik:PropertyDefinition Binding="{Binding Friend}" GroupName="General" DisplayName="Best Friend" OrderIndex="3" />
</telerik:RadPropertyGrid.PropertyDefinitions>
</telerik:RadPropertyGrid>
I do see that the original source for this thread had a CurrentPeople
model object with fields that serves as the data source for the ViewModel that is the DataContext for the RadPropertyGrid. The RadPropertyGrid binds to public properties that are in turn backed by model member properties. Does this mean I have to construct a phony object model or Viewmodel of just the properties I care to manage this way? Seems a convoluted approach, particularly the use of backing private fields e.g. apparently unused _name for public viewmodel property Name just to get at the CurrentPeople.Name object's fields.
All of this effort for me, by the way, is aimed at setting properties in the User configuration like 'Logging Level' or 'Telerik Theme To Use' or 'Default Date'., so really I would really like to just bind the RadPropertyGrid to one or several of the User.Config settings directly and be done with this. I already have a dialog for most of the properties but I wanted to provide the generic one for access to some less important ones like the log config file name and so on that normally don't ever change but might need to be changed for special circumstances. This seems like such a common need that I wonder why the 'Getting Started' does not address it directly as an example?
Any help would be appreciated.
Thank you.
@Hontas. What do you mean by saying "full binding support"? It has full binding support, but it also still has to respect the core binding concepts of .NET framework. ElementName binding works in a single name scope. According to the reasons that I have listed in the previous post of mine, the PropertyDefinition instance and the CheckBox are in separate name scopes, so that your approach does not work. This is absolutely expected.
As for the second code snippet of yours, you are binding the Visibility property like this:
<
telerik:PropertyDefinition
Binding
=
"{Binding VisaNo}"
GroupName
=
"General"
DisplayName
=
"VisaNo"
OrderIndex
=
"2"
Visibility
=
"{Binding Path=IsChild, Converter={StaticResource converter}}"
/>
@Allen Basically, in order to use RadPropertyGrid you only need a clr object that exposes the public properties, which values you want to display/modify. As RadPropertyGrid works exclusively with framework's binding mechanism, it cannot "read" field values, unless they are backed with the appropriate public properties. You have mentioned that you want to bind the control to one or several items. In order to achieve this, you do not need to create a fake ViewModel that exposes their properties. You can alternatively use the PropertySets feature of RadPropertyGrid. I have prepared a simple example project for your that illustrates how it works. I am attaching it for your reference.
Guys, we will be glad to provide additional assistence to you, if it is needed, so that do not hesitate to contact us in case any additional inquiries occur.
Regards,
Ivan Ivanov
the Telerik team
public class vm : GalaSoft.ViewModelBase
..
private string _blah = String.Empty;
public string Blah
{get
{return _blah;}
}
{set
{_blah = value;
RaisePropertyChanged("Blah);
}
public vm()
{
Blah = Properties.Default.BlahUserWriteableProperty;
...
...
...
// more properties from Properties.Default.....
...
...
...
}
public SaveProperties()
{
Properties.Default.BlahUserWriteableProperty= Blah;
}
...
...
so I want the RPG Item to be
Item = vm;
for which a property grid thing-me will be created for each public property.
But I think you are telling me I need to do this:
/// model
public IList<object> PropertiesBasket {
ClassA ClassAProperties;
ClassB ClassBProperties;
ClassC ClassCProperties;
public PropertiesBasket()
{
ClassAProperties = new ClassA();
ClassAProperties.Load();
ClassBProperties= new ClassB();
ClassBProperties.Load();
ClassCProperties = new ClassC();
ClassCProperties.Load();
etc. etc. etc. etc. for the set of user writeable Properties.Settings of interest (may or may not be all of them...)
}
}
So nutshell:
Create subclasses for each type of property in Properties.Settings
Provide initialization method in the subclasses to load the settings from Properties.Default......
Provide save method in the subclasses to persist the settings to Properties.Default......
Create a complex object made up of these sub classes
Initialize the subclasses as the complex object is created
Bind rpg control to the complex object.
Magic ensues.
Am I understanding this correctly? This complex object seems a lot like a ViewModel to me..... particularly if it has additional methods or whatever. That actually may be ideal because other views can bind to it that are for other purposes....
I guess my point is there is an awful lot to do to use the rpg to just edit Properties.Default for user settings that are volatile. But if it will work as I have sketched (badly) then thank you.
Please, excuse me for the late reply. Basically both approaches would be viable, but preparing a common view model class that exposes all of your items' properties would demand lots of additional effort on your side compared to just binding the RadPropertyGrid to a collection of these items, relying on its internal logic to construct the view model on its own. Moreover, you would be able to be benefit from the alternating Union/Intersection property set modes. I would advise you to give it a try so that you could
determine whether this is an appropriate solution for your case. Please, do not hesitate to contact us again if you have any further inquiries on this.
Kind regards,
Ivan Ivanov
the Telerik team
What i need is to set Visibility of a PropertyDefinition at runtime. For example i created 2 properties in PropertyGrid. One property is the type Visibility, another is the type string. When i select the first property as true, the second property should be shown and then man can edit the value of it.
I tried to bind these two properties with ViewModel. But that dose not work. When i write the values hard coded in xaml. That works. But that will not be changed any more. I have also tried with binding a bool value and combining with a BooleanToVisibilityConverter. That dose not work either.
Please give some suggestion, how do i resolve this problem. Thanks.
I am attaching a sample project that illustrates how to achieve this.
Regards,Ivan Ivanov
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Hi Ivan, excuse me for posting my question on a dead thread. But I'm facing the same issue, and I get here.
Your sample project works well. But my problem is that I cannot make my ViewModel as static resource since the view model is created at runtime. And I tried to bind Visibility Property as below, but it does not work. rpg is the name of the telerik:RadPropertyGrid. Would you please guide me how to work it out? Thanks in advance!
<telerik:PropertyDefinition OrderIndex=
"3"
Binding=
"{Binding Interval}"
Description=
"Interval"
Visibility=
"{Binding Path=Item.Periodically, ElementName=rpg, Converter={StaticResource bool2Visibility}}"
>
I modified my initial project to respect the scenario when view model is generated at run-time. I am attaching it for your reference.
Regards,
Ivan Ivanov
Telerik
Hi Ivan!
Thanks for your reply. It works!
And I notice that you implement this in code behind. So, I'm wondering if there is easy way to do this inside xaml?
I am afraid that no valid XAML only solution comes to my mind. The trick is that PropertyDefinitions are not visual elements and the derive from DependencyObject. The DependencyObject type provides data binding support, but it relies on explicitly set binding source. Thus not having it defined as a resource, which can be reference complicates things a lot. However, you can try using an attached behavior that modifies or load the property definition, as soon as the view model gets loaded. Indeed, it is not a pure xaml solution, but the code will be separate from the view's code-behind class.
Regards,
Ivan Ivanov
Telerik
Hi Ivan,
I used the approach in your example project RadGridView-WPF-AR-19. It works for setting the Visibility binding of my PropertyDefinitions from the code-behind, but there was a negative side-effect. In the case that the Visibility is set to false, all the bindings of the PropertyDefintions below seem to get mangled showing zeros and NaN rather than the values of their bound viewmodel properties.
Please advise.
Is the described problem reproducible after modifying the original example project? If not, would it be possible for you to open a support ticket, which enables zip attachments and priority support. Sending a repro-project that illustrates the problem would help us a lot to pinpoint its source and suggest an appropriate solution.
Regards,
Ivan Ivanov
Telerik