Current filter:
                                You should refresh the page.
                                  • Hello,

                                    I have a quite complicated issue in my advanced PropertyGridControl, but I managed to strip all extra code and still mantain in the same behavior as in my original project.

                                    I attached an sample project which is actually an example where I reproduced the issue.

                                    In my original project I face the situation, when a dependency property with the TypeConverterAttribute defines the specialized ExpandalbeObjectConverter which behaves in the following manner:

                                    1. The user selects a collection of paths (strings), these strings are unique indentifiers and nothing more is important about them right know .
                                        These string are stored in the dependency property named LineSources, it will help to follow the explanation as this video will.

                                    2. The LineSources property changes due a property cell editing.

                                    3. Its change then generates another collection of extra objects, it is named LineStyleDefinitions  and its every item is mapped to the original LineSources collection through the unique source identifier, but there is no other link and that collection is not browsable in the property grid control.

                                    3. Then the specialized descendant of the ExpandableObjectConverter generates virtual properties (property descriptors in GetProperties method) which should virtually define the properties of the expandable object, the string collection known as LineSources

                                    4. Those properties are actually those extra objects from the LineStyleDefinitions collection and every extra object has its own set of properties, I omit the details that they are provided using the TypeDescriptionProviderAttribute, because it is not relevant here.

                                    So, everything is working fine so far except that there the issue showed up, it is a glitch or a bug, I really don't know, but when the provided collection of the line sources, the LineSources, is initially empty, then no property defintions are generated in the ObjectToPropertyDefinitionsSourceConverter, it is correct behavior. There are other converters and selectors, but I have already found out in my so far research, that this is the point where it is probably the source of my issue, because afterward editing the LineSources collection and adding any line source, then regardless the LineStyleDefinitions are generated, they never show in the property grid. The SelectedObject has to be changed to display that virtual properties, because it is needed to re-generate the properties tree and so the virtual ones.

                                    I tried to perform the property grid invalidation calling my Refresh method, which actually calls the DataController.InvalidateSource internal method, which helped me this way refereshing the properties values and keeping the property grid in place (no collapsing/expanding/scrolling/etc.)

                                    So the attached sample should present the same thing. Altough I did a lot of debugging and observed this scenario very toroughly and found nothing wrong. The virtual properties are being generated in the right moment while the value is being set in the property grid, but the PropertyDefinitionsSource of that parent property defintions is not updated, but I cannot figure why it is so. Reselecting the currently SelectedObject does the thing, but I don't know when it is really necessary to do it, becuase if the object once had the virtual properties, then clearing the LineSources collection and selecting the same identifiers again will not trigger this issue, but when the user selects new ones, the "deeper refresh" is required.

                                    Please take a time and inspect this issue, I can provide any further explanation, but I feel that there has to be a flawless solution for this issue. Actually I guess that forcing the re-generating the property defintions will help, but I don't know how to regenerate the defintion for the single row.

                                    Best regards,
                                    Petr
                                Show all comments
                                • André (DevExpress Support) 01.14.2019

                                  Hello,

                                  Thank you for the detailed description. I've checked your project and see that in DataItemSourcesDefinitionTemplate you bind the PropertyDefinitionsSource property to a whole PropertyDataDescriptor instance that does not change, thus your binding is not reevaluated. To trigger the converter execution, you need to bind to a property that actually changes - in your case, to the Data.DataItemExtras property - using MultiBinding. I've modified your project to demonstrate this.

                                  At the same time, it would be great if you could elaborate on why you use the approach with the PropertyDefinitionsSource property binding - maybe we can offer a more suitable approach in your scenario. I look forward to your reply.

                                • Petr Stefka 01.14.2019
                                  Hi André,

                                  thank you for quick pointing to the solution, actually it is more complicated in my original project, because in have no clue to what property of data to bind the PorpertyDefintionsSource in that multibinding, but I can solve this using a specialized attribute, which will informat to what to bind in that multibinding or an attribute which will actually provide the whole template for the property defintion.

                                  I quess that there is no easier way how to accomplish this task, because I have to used this approach n my project where I have dynamic collections of parameters which are provided through the customized TypeDescriptionProvider as they are standard properties. Those parameters could dynamically chaning their writability according other states of their parents in the hierarchical structure. The parameters sources differ from the databases, various class instances and more. Here a screencast for the demonstration. 

                                  I have still problem when mutliselecting objects, so the Data in the PropertyDefintions are an IEnumerable, but I postopone that issue, but I will probably later need your further assistance.

                                  Thank you a lot for now.

                                  Petr
                                • Petr Stefka 01.14.2019
                                  Hello again,

                                  I inspected your modified sample, but there is a problem, when you edit the predefined object, then an exception raises:
                                  [HTML]
                                  v DevExpress.Xpf.PropertyGrid.Internal.DescriptorContext.<>c.<SubscribeValueChanged>b__44_0(DescriptorContext d, Object o, EventArgs e) v DevExpress.Data.Utils.WeakEventHandler`3.OnEvent(Object source, TEventArgs eventArgs) v System.EventHandler.Invoke(Object sender, EventArgs e) v System.ComponentModel.PropertyDescriptor.OnValueChanged(Object component, EventArgs e) v System.ComponentModel.ReflectPropertyDescriptor.OnValueChanged(Object component, EventArgs e) v System.ComponentModel.ReflectPropertyDescriptor.OnINotifyPropertyChanged(Object component, PropertyChangedEventArgs e) v System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e) v DevExpress.Mvvm.BindableBase.<>c__DisplayClass20_0.<RaisePropertyChanged>b__0(PropertyChangedEventHandler x) v DevExpress.Mvvm.Native.MayBe.Do[TI](TI input, Action`1 action) v DevExpress.Mvvm.BindableBase.RaisePropertyChanged(String propertyName) v DevExpress.Mvvm.Native.PropertyManager.SetProperty[T](T& storage, T value, String propertyName, Action`1 raiseNotification, Action changedCallback) v DevExpress.Mvvm.BindableBase.SetProperty[T](T& storage, T value, String propertyName, Action changedCallback) v DXSample.DataObject.set_DataItemSources(IList`1 value) v C:\Users\Scanix\Desktop\PropertyGridSample\ViewModel.cs:řádek 92
                                  I added the EditValueChanged handler for posting editing when closing (removing) a token using its close button .

                                  Petr
                                • Petr Stefka 01.14.2019
                                  Well, if the base type is DependencyObject, it works fine, I think that it is due to the delay between value change and raising of  the PropertyChanged event 

                                  [C#]
                                  public class DataObject : DependencyObject { public static readonly DependencyProperty DataItemSourcesProperty = DependencyProperty.Register(nameof(DataItemSources), typeof(IList<string>), typeof(DataObject), new PropertyMetadata(null, new PropertyChangedCallback(OnDataItemSourcesPropertyChanged))); [TypeConverter(typeof(ListToStringListExpandableTypeConverter))] public IList<string> DataItemSources { get { return (IList<string>)this.GetValue(DataItemSourcesProperty); } set { this.SetValue(DataItemSourcesProperty, value); } } private static void OnDataItemSourcesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is DataObject dataObject) { if (dataObject.DataItemSources == null || dataObject.DataItemSources.Count == 0) { dataObject.DataItemExtras = null; return; } var extraObjects = dataObject.DataItemExtras?.Where(eo => dataObject.DataItemSources.Contains(eo.DataItemSource) == true).ToList() ?? new List<ExtraObject>(); if (dataObject.DataItemSources.Count > extraObjects.Count) { var missingDataItemSources = dataObject.DataItemSources.Where(s => !extraObjects.Any(eo => eo.DataItemSource == s)).ToArray(); foreach (string dataItemSource in missingDataItemSources) { var extraObject = new ExtraObject(dataItemSource) { ExtraDash = DashStyles.Solid, ExtraInt = 1, ExtraFloat = 1.1f }; extraObjects.Add(extraObject); } } dataObject.DataItemExtras = extraObjects; } } public static readonly DependencyProperty DataItemExtrasProperty = DependencyProperty.Register(nameof(DataItemExtras), typeof(IList<ExtraObject>), typeof(DataObject), new PropertyMetadata(null)); [Browsable(false)] public IList<ExtraObject> DataItemExtras { get { return (IList<ExtraObject>)this.GetValue(DataItemExtrasProperty); } set { this.SetValue(DataItemExtrasProperty, value); } } [Browsable(false)] public new DependencyObjectType DependencyObjectType { get { return base.DependencyObjectType; } } [Browsable(false)] public new bool IsSealed { get { return base.IsSealed; } } [Browsable(false)] public new Dispatcher Dispatcher { get { return base.Dispatcher; } } }

                                • André (DevExpress Support) 01.15.2019

                                  Hello,

                                  Please give us additional time. We'll get back to you as soon as we have any news.

                                • Petr Stefka 01.15.2019
                                  Hello André,

                                  take how as much time as you need, actually I solved that problem on my side. I guess that the problem is in the internal DescriptorContext that call the setter of the property, which fires the INotifyPropertyChanged.PropertyChanged event which is changes consequentially the DescriptorContext and so the WearEventHandler  failes. This seems to be one probably explanation, because in DependencyObject, there is a delay between property change and its change notification, some messages are pumped between those calls.

                                  Petr 

                                0 Solutions

                                Creation Date Importance Sort by