Skip to main content

Microsoft Silverlight

Answered Question Datagrid template column load event, strange behavior. Might be a bugRSS Feed

(0)

PrisonBreak
PrisonBreak

Member

Member

31 points

61 Posts

Datagrid template column load event, strange behavior. Might be a bug

 Hi SL masters,

I have a very strange problem and do not know the reason causes that.

 I have a datagrid in my program which has a template column and some other regular columns. I used the template column because according to the data it contains I want it to change its backcolor. So I used a button control in my template column and added a loaded event to this button you can see the datagrid code. I implemented the loaded event in my code, I am pasting the loaded event source code, too. Now the problem: When my datagrid first loads everthing is ok the color is changed according to the condition in the event code and it works fine. The problem arises when I begin to scroll on my datagrid. The first picture below is the picture of my datagrid's first load, everthing is fine. The second picture is the picture when I scroll on my datagrid to the bottom and come back to the top. Why after some scrolling the template column changes its color randomly I can not understand...

 

The remaining of the thread through this link, please tell me if this is a bug or not and also a workaround may be...

http://silverlight.net/forums/t/27465.aspx

 

Yi-Lun Luo - MSFT
Yi-Lun L...

All-Star

All-Star

25052 points

2,747 Posts

Answered Question

Re: Datagrid template column load event, strange behavior. Might be a bug

Hello, this is by design. You need to handle the DataGrid's UnloadingRow event and remove the backgrounds of the Buttons. But I think a better solution is to use a value converter. Something like this:

Public Class MyConverter

Implements IValueConverter

Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.Convert

'Add any logic here

Dim d As Data = CType(value, Data)

If d.Name.StartsWith("a") Then

Return New SolidColorBrush(Colors.Red)

Else

Return New SolidColorBrush(Colors.Blue)

End If

End Function

Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.ConvertBack

Return Nothing

End Function

End Class

 

To use this converter, you add it to the UserControl's Resources and bound the Button's Background to the data object itself:

<UserControl.Resources>

<local:MyConverter x:Key="mc"/>

</UserControl.Resources>

<Button Content="{Binding Name}" Background="{Binding Converter={StaticResource mc}}"/>

 

shanaolanxing - I'll transfer to the Windows Azure team, and will have limited time to participate in the Silverlight forum. Apologize if I don't answer your questions in time.

PrisonBreak
PrisonBreak

Member

Member

31 points

61 Posts

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

 Hi Yi-Lun thanks for your answer I added the class to my project and modified the color conditions also made the changes in the xaml file added the code you wrote but I have an error.

"The type 'local:MyConverter' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.    D:\Documents and Settings\ar002314\My Documents\Visual Studio 2008\Projects\SilverlightApplications\LOCALSilverlightHedefGosterge\SilverlightHedefGosterge\Page.xaml"

 

How will I add this reference?  I really do not know to much about this can you explain me? I added the following line:

xmlns:local="clr-namespace:MyConverter;assembly=SilverlightHedefGosterge" and added the SilverlightHedefGosterge.dll to the references.

 

Where am I making the mistake?

sladapter
sladapter

All-Star

All-Star

17441 points

3,172 Posts

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

 If you want to add the Converter definition in your UserControl.Resources section. Add the namespace prefix definition in the UserControl Tag:

<UserControl ...

xmlns:local="clr-namespace:TheNameSpaceOfYourConverter;assembly=TheAssmeblyNameOfYourConverter"

>

<UserControl.Resources>

   <local:YourConverter x:Key="mc" />

</UserControl.Resources>

 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

Aditya Mahara
Aditya M...

Member

Member

2 points

1 Posts

Re: Datagrid template column load event, strange behavior. Might be a bug

Hi
I faced the same problem it seems that first the grid loads all the rows and then unloads the rows that does not fall under the browser height. And after that during loading and unloading the grid miscalculates the row and the corresponding data.

The idea is to make block the silverlight from unloading the Rows that are not within the browser. Well the simplest way to do that is put the grid in a scrollviewer control and set the Width="Auto" Height="Auto". 

Hope this will resolve your problem. Here is the sample code: -

<ScrollViewer Width="Auto" Height="Auto"

VerticalScrollBarVisibility="Visible" Grid.Row="0" Grid.Column="0" >

<my:DataGrid />

</ScrollViewer.Content>

</ScrollViewer>

Regards

Aditya

mikep02
mikep02

Member

Member

6 points

3 Posts

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

Hi,

Need help. I am new in silverlight.

I have these columns: Tolerance, Desired, Acual, and Variance.

I want the Variance column/cell background set to red if the difference of Desired and Actual column is not within the range set in Tolerance column.

e.g. if ((Desired - Actual) < Tolerance || (Desired - Actual) > Tolerance)

{

 // set cell background color to red

}

How can I implement this using IValueConverter?

How can I do this both in grid's edit mode and loading event.

Thanks.

sladapter
sladapter

All-Star

All-Star

17441 points

3,172 Posts

Answered Question

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

mikep02,

Use databinding to achieve what you want. Bind the background of the DataGrid Cell to the Data, use a IValueConverter.

You can use =”{Binding}” to bind without specify any particular field. Some times when you are trying to use a Converter to return a calculated value based on more than one field in the record you can use this syntax to specify binding, so the value passed to the IValueConverter will be the whole record of data which contains every fields.

In your case:

public class YourValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {

            YourDataObject data = value as YourDataObject;

            if ((data.Desired - data.Actual) < data.Tolerance || (data.Desired - data.Actual) > data.Tolerance)        
            {
                return new SolidColorBrush(Colors.Red);
            }          
        }

        ...

 }

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

mikep02
mikep02

Member

Member

6 points

3 Posts

Re: Re: Re: Datagrid template column load event, strange behavior. Might be a bug

It works!

thanks a lot Party!!!

ssawchenko
ssawchenko

Member

Member

342 points

177 Posts

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

sladapter:
You can use =”{Binding}” to bind without specify any particular field. Some times when you are trying to use a Converter to return a calculated value based on more than one field in the record you can use this syntax to specify binding, so the value passed to the IValueConverter will be the whole record of data which contains every fields.
 

 

Sorry, I'm super green with these concepts, but I'm fairly certain this is exactly what I want to do [change the background color of an entire row based on the content of one column].  Could you please give a xaml example of what you mean by the above paragraph?
For example, below I want to change the color of the background based on a given timestamp value... where would I put the ={Binding} to do this?

<Ctrls:DataGrid
            x:Name="__TabDataGrid"
            Grid.Row="1"
            AutoGenerateColumns="False">
            <Ctrls:DataGrid.Columns>
                <Ctrls:DataGridTextColumn Header="Timestamp" Binding="{Binding TimeStamp}" />
                <Ctrls:DataGridTextColumn Header="TL1" Binding="{Binding TL1Value}" />
                <Ctrls:DataGridTextColumn Header="TL2" Binding="{Binding TL2Value}" />
            </Ctrls:DataGrid.Columns>
</Ctrls:DataGrid>

sladapter
sladapter

All-Star

All-Star

17441 points

3,172 Posts

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

 If you need to change the background color of the DataGrid cell you have to use TemplateColumn and define your cell template. Because DataGridTextColumn does not have Background property that you can modify. DataGridTextColumn has Foreground property. The following XAML set the binding to the Foreground property. But can change the DataGridTextColumn to a TemplateColumn and set the binding to the Background property in the root control (say a grid) in your CellTemplate:

 <Ctrls:DataGrid.Columns>
                <Ctrls:DataGridTextColumn Header="Timestamp" Binding="{Binding TimeStamp}"  Foreground="{Binding TimeStamp, Converter={StaticResource YourColorConverter}}" />
                <Ctrls:DataGridTextColumn Header="TL1" Binding="{Binding TL1Value}" />
                <Ctrls:DataGridTextColumn Header="TL2" Binding="{Binding TL2Value}" />
            </Ctrls:DataGrid.Columns>

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

Ifti007
Ifti007

Member

Member

10 points

5 Posts

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

Hi sladapter,

Great Solution. Now can you make Foreground="{Binding TimeStamp, Converter={StaticResource YourColorConverter}}"  part of a style? Actually I have many columns and textboxes that I want to show numbers in red if numbers are negative. My converter works and I want to put it in style so that I can re-use the style for my number columns/texboxes.

 

Thanks,

Ifti

sladapter
sladapter

All-Star

All-Star

17441 points

3,172 Posts

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

 

Ifti007:

Hi sladapter,

Great Solution. Now can you make Foreground="{Binding TimeStamp, Converter={StaticResource YourColorConverter}}"  part of a style? Actually I have many columns and textboxes that I want to show numbers in red if numbers are negative. My converter works and I want to put it in style so that I can re-use the style for my number columns/texboxes. 

I'm not sure you can put the binding in a style because in each case the binding field is different.

I have been dynamically build my DataGrid Columns based on the DataType of each column. I can define a nemeric Cell Template like this (I usually put the template in a external xml file so I can reuse this template though my application):

string temp = @" <DataTemplate x:Name='NemericCell' xmlns='http://schemas.microsoft.com/client/2007'
              xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
    <Grid>
        <TextBlock HorizontalAlignment='@HorizontalAlignment@' Text='{Binding @TextBinding@}',  Foreground='{Binding @ForegroundBinding@  Converter={StaticResource YourColorConverter}}' />
    </Grid>
</DataTemplate>";

You can put this template in a external xml file so it can be reused through the application.

Code to build the column:

DataGridTemplateColumn col = new DataGridTemplateColumn();    

theGrid.Columns.Add(col);

//Replace the Token in the Template:                                
string cellTemp = temp.Replace("@HorizontalAlignment@", HorizontalAlignment.Right.ToString());
cellTemp = cellTemp.Replace("@TextBinding@", YourTextBindingFieldName);
cellTemp = cellTemp.Replace("@ForegroundBinding@", YourForegroundBindingFieldName); 

dt = XamlReader.Load(cellTemp) as DataTemplate;
col.CellTemplate = dt;  // set the Cell Template

                                      

 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

Ifti007
Ifti007

Member

Member

10 points

5 Posts

Re: Re: Datagrid template column load event, strange behavior. Might be a bug

Thanks!

aodeng
aodeng

Member

Member

6 points

6 Posts

Re: Re: Re: Datagrid template column load event, strange behavior. Might be a bug

In my code, I dynamically add columns to datagrid, and binding corresponding data field. I use DataGridTextColumn for each column. If the customer edit the data with wrong value, the cell will be highlighted. I tried to use the above method, but found the DataGridTextColumn does not have "background" property (the above example use button) . How should I do that?

my code is like this:

For i = 0 To myFieldsList.Count - 1

TextColumn = New DataGridTextColumn

TextColumn.Header = myFieldsList.Item(i).Text

TextColumn.Binding =
New Binding(myFieldsList.Item(i).ID)

uxDataGrid.Columns.Add(TextColumn)

Next

 

here I assume all data are string.

Thanks

sladapter
sladapter

All-Star

All-Star

17441 points

3,172 Posts

Re: Re: Re: Datagrid template column load event, strange behavior. Might be a bug

You could use a TemplateColumn, put a Grid around the TextBlock in the DataTemplate and set binding to the Grid.Background: 

<Grid Background='{Binding @BackgroundBinding@  Converter={StaticResource YourColorConverter}}'>
        <TextBlock HorizontalAlignment='@HorizontalAlignment@' Text='{Binding @TextBinding@}'/>
    </Grid>

 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

aodeng
aodeng

Member

Member

6 points

6 Posts

Re: Re: Re: Datagrid template column load event, strange behavior. Might be a bug

thanks, sladapter,

 

I did as your way, but no different color shows.

I use the grid binding to the same as the textblock's binding, but I never see a different color shows.

I put a break point at the converter, it never arrives.

 

sladapter
sladapter

All-Star

All-Star

17441 points

3,172 Posts

Re: Re: Re: Datagrid template column load event, strange behavior. Might be a bug

Did you leave the row after you input data?

By the way, what is the data type of the data field that bind to this column? If it's a string type, then user can put anything in the input box. But if it's a integer type and when user put something non-integer into the box, the Data Object won't even accept the new value, the new binding won't even happen.

 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities