I'm using a custom data provider, and testing suggests that some override methods are being called excessively.
The test data consists of 1 data row divided into 3 columns.
If I don't handle any events, OnHeaderValueNeeded gets called 3 times, as expected.
If I handle the CellDecorationsNeeded event, that event will be called 6 times for the same data, but OnHeaderValueNeeded is unaffected.
However, if I call FitColumnWidthToContent in the Loaded event, CellDecorationsNeeded will be called 18 times and OnHeaderValueNeeded will be called 9 times.
Calls to OnCellValueNeeded also increase from 3 to 9 when FitColumnWidthToContent is utilized.
Now perhaps I'm doing something wrong or I simply misunderstand, but of far greater concern is my override of ItemProperties, which gets called 18 times without calling FitColumnWidthToContent, and, rather oddly, 40 times when I do call FitColumnWidthToContent. This is of concern because I have some iterative code in the ItemProperties override.
Thoughts?
Wayne
5 Answers, 1 is accepted
Hello Wayne,
Thank you for the detailed description.
The behavior you described is expected as calling the FitColumnWidthToContent method in turn invokes the MeasureVertical method of the MeasurableTextElementsVisualLayer. This method then calls the OnHeaderValueNeeded method of the RadVirtualGrid control and in the case where a DataProvider is specified, this calls its OnHeaderValueNeeded method. If you're using the ItemProperties property in the OnHeaderValueNeeded method, it is expected that its getter will be invoked multiple times.
What I can suggest in this case is to cache the value of the ItemProperties to remove the overhead caused by the iteration.
I hope you found this information helpful. Please let me know if caching the properties will be possible for you.
Regards,
Dilyan Traykov
Progress Telerik
Hi Dilyan,
Thanks for your response, but I'm not quite sure what you mean by caching the value of ItemProperties in this context (I'm relatively new to WPF and still have some holes in my knowledge).
I'm building a new set of item properties in the get accessor, as follows:
List<ItemPropertyInfo> newItemProperties = new List<ItemPropertyInfo>();
ItemPropertyInfo itemProperty;
itemProperty = base.ItemProperties[0];
newItemProperties.Add(itemProperty);
for (int i = 1; i < 11; i++)
{
if (i <= GlobalObjects.CurrentQueryRequest.Breakdowns.Count)
{
itemProperty = base.ItemProperties[i];
newItemProperties.Add(itemProperty);
}
}
int maxSequenceValue = 0;
if (SecondaryValues?.Count > 0)
{
maxSequenceValue = SecondaryValues.Max(r => r.ValueSequence);
}
for (int i = 1; i <= maxSequenceValue; i++)
{
itemProperty = base.ItemProperties[i + 10];
newItemProperties.Add(itemProperty);
}
itemProperty = base.ItemProperties[13];
newItemProperties.Add(itemProperty);
itemProperty = base.ItemProperties[14];
newItemProperties.Add(itemProperty);
return newItemProperties.ToList();
...and in OnHeaderValueNeeded, I reference ItemProperties this one time using a Switch statement:
switch (this.ItemProperties[e.Index].Name) {…
So what exactly are you suggesting?
Wayne
Hi Wayne,
Thank you for the clarification.
What I have in mind by caching the ItemProperties is to introduce a new field in your custom DataProvider and use it as follows:
private List<ItemPropertyInfo> newItemProperties;
public override IList<ItemPropertyInfo> ItemProperties
{
get
{
if (newItemProperties == null)
{
newItemProperties = new List<ItemPropertyInfo>();
ItemPropertyInfo itemProperty;
itemProperty = base.ItemProperties[0];
newItemProperties.Add(itemProperty);
for (int i = 1; i < 11; i++)
{
if (i <= GlobalObjects.CurrentQueryRequest.Breakdowns.Count)
{
itemProperty = base.ItemProperties[i];
newItemProperties.Add(itemProperty);
}
}
int maxSequenceValue = 0;
if (SecondaryValues?.Count > 0)
{
maxSequenceValue = SecondaryValues.Max(r => r.ValueSequence);
}
for (int i = 1; i <= maxSequenceValue; i++)
{
itemProperty = base.ItemProperties[i + 10];
newItemProperties.Add(itemProperty);
}
itemProperty = base.ItemProperties[13];
newItemProperties.Add(itemProperty);
itemProperty = base.ItemProperties[14];
newItemProperties.Add(itemProperty);
}
return newItemProperties.ToList();
}
}
private IList<ItemPropertyInfo> newItemProperties;
public override IList<ItemPropertyInfo> ItemProperties
{
get
{
if (newItemProperties == null)
{
this.UpdateItemProperties();
}
return newItemProperties.ToList();
}
}
public void UpdateItemProperties()
{
newItemProperties = new List<ItemPropertyInfo>();
ItemPropertyInfo itemProperty;
itemProperty = base.ItemProperties[0];
newItemProperties.Add(itemProperty);
for (int i = 1; i < 11; i++)
{
if (i <= GlobalObjects.CurrentQueryRequest.Breakdowns.Count)
{
itemProperty = base.ItemProperties[i];
newItemProperties.Add(itemProperty);
}
}
int maxSequenceValue = 0;
if (SecondaryValues?.Count > 0)
{
maxSequenceValue = SecondaryValues.Max(r => r.ValueSequence);
}
for (int i = 1; i <= maxSequenceValue; i++)
{
itemProperty = base.ItemProperties[i + 10];
newItemProperties.Add(itemProperty);
}
itemProperty = base.ItemProperties[13];
newItemProperties.Add(itemProperty);
itemProperty = base.ItemProperties[14];
newItemProperties.Add(itemProperty);
}
Regards,
Dilyan Traykov
Progress Telerik
Hi Dilyan,
Makes perfect sense. Thanks for such a detailed and thorough reply!
Wayne
Hi Wayne,
You're more than welcome. Please let me know if any further questions or concerns arise.
Regards,
Dilyan Traykov
Progress Telerik