This is a migrated thread and some comments may be shown as answers.

Formatting Disappears With Virtualization Dynamic Custom Columns

2 Answers 99 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Michael
Top achievements
Rank 1
Michael asked on 30 Mar 2010, 08:06 PM
This thread relates to http://www.telerik.com/community/forums/silverlight/gridview/images-disappear-when-scrolling-in-gridview.aspx

I am creating a custom data column type

I have created a few converter classes to help:

using System;  
using System.Net;  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Documents;  
using System.Windows.Ink;  
using System.Windows.Input;  
using System.Windows.Media;  
using System.Windows.Media.Animation;  
using System.Windows.Shapes;  
using System.Windows.Data;  
using System.Globalization;  
 
namespace ABC.SLApp1  
{  
    public class TemplateNameBackgroundConverter : IValueConverter  
    {  
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
            return (string)value + "_BackgroundColor";  
        }  
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
            string stemp = (string)value;  
            return stemp.Substring(0, stemp.IndexOf("_"));  
        }  
    }  
 
    public class TemplateNameForegroundConverter : IValueConverter  
    {  
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
            return (string)value + "_ForegroundColor";  
        }  
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
            string stemp = (string)value;  
            return stemp.Substring(0, stemp.IndexOf("_"));  
        }  
    }  
 
    public class RFBackgroundConverter : IValueConverter  
    {  
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
            string hexColor = (string)value;  
 
            if (!string.IsNullOrEmpty(hexColor))  
            {  
 
                if (hexColor.Length == 7)  
                    return new SolidColorBrush(Colors.Green);  
                return new SolidColorBrush(Colors.Yellow);  
            }  
 
            return new SolidColorBrush(Colors.White);  
        }  
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
            Color cTemp = ((SolidColorBrush)value).Color;  
 
            return string.Format("#{0:x}{1:x}{2:x}{3:x}", cTemp.A, cTemp.R, cTemp.G, cTemp.B);  
        }  
    }  
 
    public class RFForegroundConverter : IValueConverter  
    {  
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
            string hexColor = (string)value;  
 
            if (!string.IsNullOrEmpty(hexColor))  
            {  
                if (hexColor.Length == 7)  
                    return new SolidColorBrush(Colors.Gray;  
                return new SolidColorBrush(Colors.  
            }  
 
            return new SolidColorBrush(Colors.Orange);  
        }  
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)  
        {  
            Color cTemp = ((SolidColorBrush)value).Color;  
 
            return string.Format("#{0:x}{1:x}{2:x}{3:x}", cTemp.A, cTemp.R, cTemp.G, cTemp.B);  
        }  
    }  

Where a grid is set up like so:
_____________________________________________________________________________________
MetricName1_Value| MetricName1_BackgroundColor| MetricName1_ForegroundColor | MetricName2_Value ...

Since the names of these metrics are dynamic, I have set the columns in code:
new CustomDataColumn  
                {  
                    MatricName = m.MetricName,  
                    UniqueName = "Matrix_" + m.MatricName,  
                    DataType = Type.GetType(m.DataType),  
                    IsFilterable = true,  
                    IsReadOnly = true,  
                    IsSortable = true,  
                    Header = textBlockHeader,  
                    HeaderCellStyle = Resources["HeaderCellStyle"as Style,  
                    CellStyle = Resources["RFCellStyle"as Style,  
                    DataMemberBinding = new Binding(m.MatricName + "_Value"),  
                    Width = 50,  
                    MinWidth = 30,  
                    TextAlignment = TextAlignment.Center   
                }; 

RFCellStyle is defined as:
<Style x:Key="RFCellStyle" TargetType="grid:GridViewCell">  
    <Setter Property="Template" Value="{StaticResource RFCellTemplate}"/>  
</Style> 

but I am trying to have a dynamic conversion. 
I've tried to use it in the XAML, but this would require nested binding statements in the ControlTemplate, not to mention I would need to know the Metric name ahead of time. 

I've tried something like:

Style RFCellStyle = new Style("grid:GridViewCell");  
RFBackgroundConverter rFBgConv = new RFBackgroundConverter();  
 
RFCellStyle.Setters.SetValue(Control.BackgroundProperty, rFBgConv.Convert(new Binding(m.MatricName + "_BackgroundColor"), typeof(String), null, System.Globalization.CultureInfo.InvariantCulture));  
RFCellStyle.Setters.SetValue(Control.ForegroundProperty, rFBgConv.Convert(new Binding(m.MatricName + "_ForegroundColor"), typeof(String), null, System.Globalization.CultureInfo.InvariantCulture));  
 
var col = new CustomDataColumn  
                {  
                    MatricName = m.MatricName,  
                    UniqueName = "Matrix_" + m.MatricName,  
                    DataType = Type.GetType(m.DataType),  
                    IsFilterable = true,  
                    IsReadOnly = true,  
                    IsSortable = true,  
                    Header = textBlockHeader,  
                    HeaderCellStyle = Resources["HeaderCellStyle"as Style,  
                    CellStyle = RFCellStyle,  
                    DataMemberBinding = new Binding(m.MatricName + "_Value"),  
                      
                    Width = 50,  
                    MinWidth = 30,  
                    TextAlignment = TextAlignment.Center   
                }; 

Of course, my converter receives a binding data type, which doesn't work.


I've also tried overriding CreateCellElement

 

public override FrameworkElement CreateCellElement(GridViewCell cell, object dataItem) in CustomDataColumn class,

but this too fails on virtualization (it leaves some blank columns formatted, as though createcellelement is not being called.)

 

var presenter = new TextBlock();  
 
            var opp = dataItem as DynamicObject;  
            if (opp == nullreturn presenter;  
 
            var metrics = opp.GetValue<OpportunityMetric>(MatricName);  
            if (metrics == nullreturn presenter;  
 
            presenter.SetBinding(TextBlock.TextProperty, new Binding  
              {  
                 Path = new PropertyPath(DataMemberBinding.Path.Path),  
                 Mode = BindingMode.OneWay  
              }); 
if (!string.IsNullOrEmpty(metrics.BackgroundColor))  
  cell.SetValue(Control.BackgroundProperty, new SolidColorBrush(Colors.Gray));  
else 
  cell.SetValue(Control.BackgroundProperty, new SolidColorBrush(Colors.White)); 

Any thoughts would be more than welcome. Please let me know how I can assist.

 

 

2 Answers, 1 is accepted

Sort by
0
Michael
Top achievements
Rank 1
answered on 31 Mar 2010, 02:07 PM
Essentially, when virtualization is off, the cells are rendered correctly, but when virtualization is on, it does not repaint (or refresh) the cell's dependency properties, such as background color, if there is no data in those cells. It will update the value, but not formatting properties. 

So far I've placed a breakpoint on the  override of GetCellContent, but obviously cannot set the cell's properties there. I've also tried manipulating CreateCellElement, which works when there is data but not when there are nulls.

Perhaps in the next release.

I am currently using the 2010 Q1 beta.

Thanks.
0
Michael
Top achievements
Rank 1
answered on 31 Mar 2010, 03:30 PM
Moral of this story is to be sure when you override something that you override it completely.

The rad grid will get the value automatically and inherently.

so for 

public

 

override FrameworkElement CreateCellElement(GridViewCell cell, object dataItem)

be sure to set 

 

cell.SetValue(

Control.BackgroundProperty, new SolidColorBrush(Colors.Transparent));

 

cell.SetValue(

Control.ForegroundProperty, new SolidColorBrush(Colors.Black));

as a default. (or whatever defaults you want) before you return the function.

 

Tags
GridView
Asked by
Michael
Top achievements
Rank 1
Answers by
Michael
Top achievements
Rank 1
Share this question
or