Skip to main content
Home Forums Silverlight Programming Report a Silverlight Bug Datagrid template column load event, strange behavior. Might be a bug
16 replies. Latest Post by sladapter on October 15, 2009.
(0)
PrisonBreak
Member
31 points
61 Posts
09-17-2008 5:19 AM |
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 L...
All-Star
25052 points
2,747 Posts
09-19-2008 3:15 AM |
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:
End
To use this converter, you add it to the UserControl's Resources and bound the Button's Background to the data object itself:
09-19-2008 8:00 AM |
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
17441 points
3,172 Posts
09-19-2008 9:19 AM |
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>
Aditya M...
2 points
1 Posts
09-28-2008 4:12 PM |
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: -
<
</
Regards
Aditya
mikep02
6 points
3 Posts
04-23-2009 9:34 PM |
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.
{
// 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.
04-24-2009 4:37 PM |
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); } }
...
04-24-2009 11:18 PM |
It works!
thanks a lot
ssawchenko
342 points
177 Posts
09-28-2009 12:44 PM |
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>
09-29-2009 4:05 AM |
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>
Ifti007
10 points
5 Posts
10-09-2009 1:39 AM |
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
10-09-2009 4:19 PM |
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
10-11-2009 5:52 PM |
Thanks!
aodeng
6 Posts
10-15-2009 4:01 PM |
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.Header = myFieldsList.Item(i).Text
uxDataGrid.Columns.Add(TextColumn)
here I assume all data are string.
Thanks
10-15-2009 4:39 PM |
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>
10-15-2009 6:40 PM |
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.
10-15-2009 9:33 PM |
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.