Telerik Forums
UI for Silverlight Forum
12 answers
170 views
Hi...

When I add PropertyDefinitions to the PropertyDefinitions member of a PropertyGrid, if they have NestedProperties, they are collapsed by default (i.e. the plus sign is visible, not the minus sign, and the nested properties are not yet visible).  But when I add to the NestedProperties of a ProprtyDefinition, those properties are expanded by default (i.e. the minus sign is visible, and the nested properties are visible).  Is there a way to control this?  In most cases, I'd always want them collapsed by default (this would be much more performant, because it won't try to load everything at once), but ideally I'd use a property of the PropertyDefinition I'm adding, or of the PropertyDefinitionCollection I'm adding to, so I could have complete control of this.

Thanks,

-Ari
Lakshman
Top achievements
Rank 1
 answered on 06 Jun 2020
19 answers
273 views
Hi,

The property editor is split in 2 columns:

Label Column
Editor Column

I want to create a property editor with following features:

It must show a readonly textbox that contains the path of a file
At the right side i must have a button that allows opening a filedialog
I do not want the property editor to show a horizontal scrollbar

I have created a readonly textbox that contains the path of the file, it will contain a button with which i can open a filedialog. I have made a template that will show a texttrimmed textblock. So far so good...

I know the horizontal scrollbar can be turned of in the property editor. But the textbox always resizes so it can show the entire path. This means that if the text in it is to long, i will not see the button on the right.

I have found there is a property for the Width of the label column but not for the width of the editor column, so how can i set the MaxWidth of my editor match the width of the Editor column?

What i want to achieve is like the visual studio property editor... that there is no horizontal scrollbar shown at any time... but that the user would have to resize the propertygrid for seeing the entire path of the file.

Is this possible?


Dilyan Traykov
Telerik team
 answered on 14 Jan 2020
1 answer
39 views

Hi!

If i remove some property definition at runtime on code behind, then all other definition is only readonly on UI. I debugging the property definition list, but show is readonly = false after remove items, however UI is disabled.

The removed item is properly removed from UI.
What the problem?

This code using to remove:
EditProperty.PropertyDefinitions.RemoveRange(EditProperty.PropertyDefinitions.Where(x => x.OrderIndex == 500).ToList());

Vladimir Stoyanov
Telerik team
 answered on 16 May 2019
0 answers
55 views

Usage:

[System.ComponentModel.DataAnnotations.Range(0, 2)]
//[Display(...)]
public int UpperLabelColumn
{
    get { return _upperLabelColumn; }
    set { Set(() => UpperLabelColumn, ref _upperLabelColumn, value); }
}

In XAML:

<DataTemplate >
    <t:RadNumericUpDown t:AutoBindBehavior.UpdateBindingOnElementLoaded="Value" IsInteger="True">
        <i:Interaction.Behaviors>
            <bs:RadNumericUpDownAttributeBehavior />
        </i:Interaction.Behaviors>
    </t:RadNumericUpDown>
</DataTemplate>

Implementation:

public class RadNumericUpDownAttributeBehavior : Behavior<RadNumericUpDown>
{
    protected override void OnAttached()
    {
        AssociatedObject.Loaded += OnLoaded;
        AssociatedObject.DataContextChanged += OnDataContextChanged;
    }
 
    protected override void OnDetaching()
    {
        AssociatedObject.Loaded -= OnLoaded;
        AssociatedObject.DataContextChanged -= OnDataContextChanged;
    }
 
    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        UpdateBinding((RadNumericUpDown) sender);
    }
 
    private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        UpdateBinding((RadNumericUpDown)sender);
    }
 
    private void UpdateBinding(RadNumericUpDown sender)
    {
        var binding = sender.GetBindingExpression(RadRangeBase.ValueProperty);
 
        if (binding == null)
            return;
 
        var attributes = GetCustomAttributes(binding.DataItem, binding.ParentBinding.Path.Path);
 
        if (attributes == null || attributes.Length == 0)
            return;
 
        var rangeAttribute = attributes.OfType<RangeAttribute>().FirstOrDefault();
 
        if (rangeAttribute == null)
            return;
 
        sender.Minimum = Convert.ToDouble(rangeAttribute.Minimum);
        sender.Maximum = Convert.ToDouble(rangeAttribute.Maximum);
    }
 
    protected static object[] GetCustomAttributes(object source, string propertyPath)
    {
        if (source == null || string.IsNullOrEmpty(propertyPath))
            return null;
 
        PropertyInfo propertyInfo = null;
 
        var currentType = source.GetType();
        var path = propertyPath.Split('.');
 
        for (int i = 0, count = path.Length; i < count; i++)
        {
            var propertyStep = path[i];
            propertyInfo = currentType.GetProperty(propertyStep);
 
            if (propertyInfo == null || source == null || i == count - 1)
                break;
 
            source = propertyInfo.GetValue(source, null);
            currentType = propertyInfo.PropertyType;
        }
 
        return propertyInfo != null ? propertyInfo.GetCustomAttributes(true) : null;
    }
}

 

Microsoft Silverlight (64-bit) Version: 5.1.41105.0
Windows 8.1 (64-bit)
Internet Explorer 11.0.9600.17416
Telerik 2017.1.117.1050

 

Art
Top achievements
Rank 1
 asked on 19 Feb 2017
0 answers
35 views

Hello! I found this discussion. 08 Oct 2014 Yoan says:

"I am afraid that this functionality is not supported since there are some conceptual impediments that prevent us to change the implementation of RadPropertyGrid. However, I have logged this in our system as feature request..."

Anyway, I spent a couple of hours and just put it here. All we need is:

  1. ControlTemplate of the PropertyGridFieldTemplate, defined in ResourceDictionary (Theme);
  2. NestedPropertyVisibilityBehavior
  3. PreventNestingAttribute

In the ControlTemplate find "PART_NestedPropertiesButton" and replace it with

<t:RadToggleButton x:Name="PART_NestedPropertiesButton"
        Style="{StaticResource PropertyGridNestedToggleButtonStyle}"
        Background="Transparent"
        Width="25"
        IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsExpanded, Mode=TwoWay}">
    <i:Interaction.Behaviors>
        <behaviors:NestedPropertyVisibilityBehavior PropertyGridField="{Binding RelativeSource={RelativeSource TemplatedParent}}"
 ShouldDisplayNestedProperties="{Binding ShouldDisplayNestedProperties, RelativeSource={RelativeSource TemplatedParent}}"/>
    </i:Interaction.Behaviors>
</t:RadToggleButton>

 

Behavior class:

public class NestedPropertyVisibilityBehavior : Behavior<RadToggleButton>
{
    public static readonly DependencyProperty PropertyGridFieldProperty =
        DependencyProperty.Register("PropertyGridField", typeof (PropertyGridField),
            typeof (NestedPropertyVisibilityBehavior), new PropertyMetadata(null, OnPropertyGridFieldChanged));
 
    public static readonly DependencyProperty ShouldDisplayNestedPropertiesProperty =
        DependencyProperty.Register("ShouldDisplayNestedProperties", typeof (bool),
            typeof (NestedPropertyVisibilityBehavior), new PropertyMetadata(false, OnShouldDisplayNestedPropertiesChanged));
 
    private bool _preventNesting;
 
    public PropertyGridField PropertyGridField
    {
        get { return (PropertyGridField)GetValue(PropertyGridFieldProperty); }
        set { SetValue(PropertyGridFieldProperty, value); }
    }
 
    public bool ShouldDisplayNestedProperties
    {
        get { return (bool)GetValue(ShouldDisplayNestedPropertiesProperty); }
        set { SetValue(ShouldDisplayNestedPropertiesProperty, value); }
    }
 
    private static void OnShouldDisplayNestedPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var sender = (NestedPropertyVisibilityBehavior) d;
        sender.UpdateVisibility();
    }
 
    private static void OnPropertyGridFieldChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var field = e.NewValue as PropertyGridField;
 
        if (field == null)
            return;
 
        var propDef = field.DataContext as PropertyDefinition;
 
        if (propDef == null)
            return;
 
        var attrs = GetCustomAttributes(propDef.Instance, propDef.SourceProperty.Name);
        var sender = (NestedPropertyVisibilityBehavior) d;
 
        sender._preventNesting =  attrs.Any(x => x is PreventNestingAttribute);
        sender.UpdateVisibility();
    }
 
    protected override void OnAttached()
    {
        UpdateVisibility();
    }
 
    private void UpdateVisibility()
    {
        if (AssociatedObject == null)
            return;
 
        AssociatedObject.Visibility = ShouldDisplayNestedProperties && !_preventNesting
            ? Visibility.Visible
            : Visibility.Collapsed;
    }
 
    protected static object[] GetCustomAttributes(object source, string propertyPath)
    {
        if (source == null || string.IsNullOrEmpty(propertyPath))
            return null;
 
        PropertyInfo propertyInfo = null;
 
        var currentType = source.GetType();
        var path = propertyPath.Split('.');
 
        for (int i = 0, count = path.Length; i < count; i++)
        {
            var propertyStep = path[i];
            propertyInfo = currentType.GetProperty(propertyStep);
 
            if (propertyInfo == null || source == null || i == count - 1)
                break;
 
            source = propertyInfo.GetValue(source, null);
            currentType = propertyInfo.PropertyType;
        }
 
        return propertyInfo != null ? propertyInfo.GetCustomAttributes(true) : null;
    }
}

 

Attribute:

[AttributeUsage(AttributeTargets.Property)]
public sealed class PreventNestingAttribute : Attribute { }

 

Usage in your Settings item:

[PreventNesting]
//[Display(Name = "Margin")]
public Thickness Margin
{
    get
    {
        return _margin;
    }
 
    set { Set(() => Margin, ref _margin, value); }
}

 

I would be happy if it can be made more compact. I made it in haste.

 

Microsoft Silverlight (64-bit) Version: 5.1.41105.0
Windows 8.1 (64-bit)
Internet Explorer 11.0.9600.17416
Telerik 2017.1.117.1050

Art
Top achievements
Rank 1
 asked on 19 Feb 2017
0 answers
31 views

I have many instances of same class A. And there is several properties of class B inside A, which can be expanded in PropertySetMode="None".

But when I trying to edit multiple objects by passing IEnumerable<object> of A as Item, there is no expanders in Union/Intersect modes.

This is understandable for the Union, but not for Intersect, where only same properties presented.

Maybe I can use the DataTemplateSelector or something else to solve this problem?

 

Microsoft Silverlight (64-bit) Version: 5.1.41105.0
Windows 8.1 (64-bit)
Internet Explorer 11.0.9600.17416
Telerik 2017.1.117.1050

Art
Top achievements
Rank 1
 asked on 18 Feb 2017
1 answer
107 views

In my project I use RadPropertyGrid. I can't set custom editors in xaml because I don't know properties of PropertyGrid.Item in design mode.
I defined PropertyDefinition and set EditorTemplate in run time.

<DataTemplate x:Name="CustomComboBox">
   <ComboBox telerik:AutoBindBehavior.UpdateBindingOnElementLoaded="SelectedValue" SelectionMode="Single" Loaded="ComboBox_Loaded"/>
</DataTemplate>

I have dynamically set some properties of Editors in Loaded() event (for example ItemsSource for ComboBox).

I use PropertyGridField.AutoGeneratedPath to define witch editor is loading.

private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
   string propertyName = ((PropertyDefinition)((PropertyGridField)((ComboBox)sender).Parent).DataContext).AutoGeneratedPath;
   //creating itemsList...
   ((ComboBox)sender).ItemsSource = itemsList;
   ((ComboBox)sender).DisplayMemberPath = "DisplayName";
   ((ComboBox)sender).SelectedValuePath = "Code";
}

In EditMode="Default" it works fine.

If I set EditMode to Single this solution will not work.

In Loaded() event sender.Parent = null.

Dilyan Traykov
Telerik team
 answered on 19 Oct 2016
1 answer
27 views

In Single EditMode value of property is displayed in TextBlock.
How can I add a custom control instead this TextBlock?

Stefan Nenchev
Telerik team
 answered on 19 Oct 2016
6 answers
281 views
Hi...

I'm trying to build out a dynamic editor using the PropertyGrid.  I have had success getting the hierarchy working, but I'm running into trouble when I try to bind the data.  So far, I've tried it two different ways: first, by exposing a Dictionary<string, string> (I'll leave out any type issues, and just pretend that all my non-hierarchical fields are strings, for now), and second using dynamic types.  So, I set up the PropertyGrid, pretty simply in the xaml:

<telerik:RadPropertyGrid x:Name="propertyGrid1" Grid.Column="1"
                                 SearchInNestedProperties="True"
                                 Width="620" Height="400"
                                 AutoGenerateBindingPaths="False"
                                 AutoGeneratePropertyDefinitions="False"
                                 NestedPropertiesVisibility="{Binding IsChecked, ElementName=CheckBox1, Converter={StaticResource converter}}"
                                 DescriptionPanelVisibility="Collapsed"/>

Then, so that I can play with things, I'm adding PropertyDefinitions to propertyGrid1.PropertyDefinitions when a button is clicked.  I created a simple class with a dictionary of strings in it called MyEntity:

        public class MyEntity : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            public void AddString(string key, string value)
            {
                _stringVal.Add(key, value);
            }

            private Dictionary<string, string> _stringVal = new Dictionary<string, string>();
            public Dictionary<string, string> StringVal
            {
                get
                {
                    return _stringVal;
                }

                set
                {
                    if (value != _stringVal)
                    {
                        _stringVal = value;
                        NotifyPropertyChanged("StringVal");
                    }
                }
            }

            private void NotifyPropertyChanged(string name)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

Here's the class that corresponds to the xaml above:

public partial class Example : UserControl, INotifyPropertyChanged
{
        private MyEntity _ent = new MyEntity();
        
        public Example()
        {
            InitializeComponent();
            _ent.AddString("Item0", "000");
            _ent.AddString("Item1", "111");
            _ent.AddString("Item2", "222");
            DataContext = _ent;
        }
       
        private void Button_Click(object sender, RoutedEventArgs e)
        {
              var topDef = new PropertyDefinition()
                {
                    DisplayName = "Top Item " + propertyGrid1.PropertyDefinitions.Count.ToString(),
                    Binding = new Binding("StringVal[Item0]")
                    {
                        Path = new PropertyPath("StringVal[Item0]")
                    },
                    OrderIndex = propertyGrid1.PropertyDefinitions.Count,
                    IsReadOnly = false
                };
            propertyGrid1.PropertyDefinitions.Add(topDef);
        }
}

I can't get the data to bind though.  The PropertyGrid comes up, with no errors, but the properties seem to be considered null.  I can get bindings to work with paths like "StringVal[Item0]" using other controls, but not PropertyDefinitions.

I've also tried this using a dynamic type (i.e. derived from DynamicObject), instead of the MyEntity class that contains the  dictionary, and gotten the same result.  I prefer that approach, but thought that showing it this way would be simpler to understand.

Am I way off base here, or just missing something simple?

Thanks,

-Ari
Stefan Nenchev
Telerik team
 answered on 02 Sep 2016
5 answers
119 views
Regarding your demo http://demos.telerik.com/silverlight/#PropertyGrid/Virtualization

I want to know how can I validate property in RadPropertyGrid?

EX:
- Property 1 is required
- Property 2 max string length 50
...

Regards,




Yoan
Telerik team
 answered on 23 Feb 2016
Top users last month
horváth
Top achievements
Rank 2
Iron
Iron
Steve
Top achievements
Rank 2
Iron
Erkki
Top achievements
Rank 1
Iron
Mark
Top achievements
Rank 2
Iron
Iron
Veteran
Jakub
Top achievements
Rank 1
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?