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

[Solved] Storyboard/ColorAnimation for GridViewCell background

6 Answers 138 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Chris
Top achievements
Rank 1
Chris asked on 15 Jul 2011, 09:27 AM
Hi,

I've implemented a CellStyleSelector that is currently setting the background color of a GridViewCell depending on the state of the 'item' parameter object of the SelectStyle override.

This has been done by having a style setup in the xaml as per:

<y:CellStyle.ChangedCellStyle>
    <Style TargetType="telerik:GridViewCell">
        <Setter Property="Background" Value="#D7F394" />
    </Style>
</y:CellStyle.ChangedCellStyle>


I then have a CellStyle class in the code behind derived from StyleSelector:

public class CellStyle : StyleSelector
{
    public override Style SelectStyle(object item, DependencyObject container)
    {
          .... etc etc - returns a Style based on state of 'item'


And then finally, because the GridView columns are created in the code behind, the CellSelector is set as follows:

var newColumn = new GridViewDataColumn
    {
        Header = header,
        DataMemberBinding = binding,
        TextAlignment = selectedDataColumn.Alignment,
        HeaderTextAlignment = TextAlignment.Center,
        CellStyleSelector = new CellStyle(),
    };


I now want to change this so that, instead of having a solid background color, I can have a ColorAnimation from a solid color to transparent.

I know I need a StoryBoard resource in my xaml but I'm not sure how to then use that in the StyleSelector or if I even can...

I've seen Pavel's example which uses a template for the cell but is there any way to achieve this without moving to that and just continue to use the StyleSelector?

Any guidance would be great.

6 Answers, 1 is accepted

Sort by
0
Ivan Ivanov
Telerik team
answered on 15 Jul 2011, 12:15 PM
Hello Chris,

I would strongly advise you to utilize the approach from Pavel's blog, in order to accomplish this task. Setting this storyboard through a style will be a rather cumbersome task, since you will have to  place the storyboard is GridViewCell's template. I think that retemplating GridViewCell would prove to be a rather unnecessary effort in your case.

Best wishes,
Ivan Ivanov
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Chris
Top achievements
Rank 1
answered on 15 Jul 2011, 12:46 PM
Thanks Ivan - since my earlier post, I have been spending time moving to the template approach from Pavel's blog and now have an early working version of it working so yep, I agree with your advice.
0
Chris
Top achievements
Rank 1
answered on 28 Jul 2011, 12:26 PM
An update on this:

I've had it all successfully working with a cell template as suggested (every cell uses the same template - it just has a textblock) - the grid has a DataTable set as ItemsSource and new rows, or property changes to existing rows result in nice animated color fades to new or updated cells.

The DataTable is a custom one and has INotifyCollectionChanged implemented and also each DataRow has INotifyPropertyChanged implemented so the grid updates automatically when any properties change.

However, due to a problem I had similar to this post (http://www.telerik.com/community/forums/silverlight/gridview/virtual-mode-custom-cell-datatemplate-problems.aspx) I had the following in my gridview definition:

EnableRowVirtualization="False" EnableColumnVirtualization="False"


Now, due to another issue I'm trying to solve, I wanted to try it with them switched on again.  After I've done this none of the fades work anymore.  It goes into my (equivalent to Pavel's) UpdateUI method in the template but the DataContext member is always the same - i.e. is not relevant to the cell that's being updated.  The binding must be correct as the cell text (TextBlock.Text) updates but I'm using two properties in the DataContext object to check how the cell has changed (to apply two different types of fade).  Because the DataContext is always the same (it's actually from a cell that hasn't changed) it doesn't go into the code that begins the StoryBoard animations.

The reason for turning the Virtualization back on again is to try and solve my second problem:  Say I have the rows A,B,C,D in my grid.  The DataTable is updated from an external source every 3 seconds.  If a new row C1 gets added to the DataTable I end up with A,B,C,C1,D with the animating color fade going for 15 seconds in all cells on row C1.  If, within that 15 seconds another new row comes into the DataTable, say A1, I end up with A,A1,B,C,C1,D with a new color fade happening in all cells on row A1.  The problem is that because the rows have shifted down due to A1 going in, the color fade that started on row C1 doesn't shift down and the fade continues but in all the cells on row C.

Any ideas on how to solve these two?
0
Chris
Top achievements
Rank 1
answered on 28 Jul 2011, 02:25 PM

Since my last post I took the time to adjust Pavel's original code to implement a "new row" approach so that I could hopefully replicate a similar problem in it - but it works fine so at least I know its not a problem with the Telerik Grid.

I changed the LiveDataMock.cs code as follows (the List changed to an ObservableCollection and I added an AddRandomPrice function to call instead of the UpdateRandomPrice.

public class LiveDataMock
{
    static LiveDataMock()
    {
        random = new Random();
        DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(3) };
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();
        var fakeCompanyNames = new[] { "Acme, inc." , "Widget Corp", "123 Warehousing", "Demo Company", "Smith and Co.", "Foo Bars", "ABC Telecom"};
        companies = new ObservableCollection<CompanyInfo>();
        fakeCompanyNames.ToList().ForEach(c =>
        {
            CompanyInfo compInfo = new CompanyInfo() { CompanyName = c, StockPrice = System.Convert.ToDecimal(random.NextDouble() * 500), OldStockPrice = System.Convert.ToDecimal(random.NextDouble() * 500) };
            companies.Add(compInfo);
        });
        //companies = (from s in fakeCompanyNames
        //             select new CompanyInfo() { CompanyName = s, StockPrice = System.Convert.ToDecimal(random.NextDouble() * 500), OldStockPrice =  System.Convert.ToDecimal(random.NextDouble() * 500) }).ToList();
    }
    static void timer_Tick(object sender, EventArgs e)
    {
        //UpdateRandomPrice();
        AddRandomPrice();
    }
    private static void UpdateRandomPrice()
    {
        decimal change = System.Convert.ToDecimal(random.NextDouble() - 0.5);
        int index = random.Next(Companies.Count);
        Companies[index].StockPrice = Companies[index].StockPrice + change;
    }
    private static void AddRandomPrice()
    {
        decimal change = System.Convert.ToDecimal(random.NextDouble() - 0.5);
        int index = random.Next(Companies.Count);
        CompanyInfo newComp = new CompanyInfo() { CompanyName = "ABC", StockPrice = Companies[index].StockPrice + change, OldStockPrice = Companies[index].OldStockPrice };
        //Companies.Add(newComp);
        Companies.Insert(3, newComp);
    }
    private static Random random;
    //private static List<CompanyInfo> companies;
    //public static List<CompanyInfo> Companies 
    //{
    //    get
    //    {
    //        return companies;
    //    }
    //}
    private static ObservableCollection<CompanyInfo> companies;
    public static ObservableCollection<CompanyInfo> Companies
    {
        get
        {
            return companies;
        }
    }
}

As said - this works fine and the ongoing fade shifts down as the new row gets inserted.

I'm seeing the only difference now is that we're always adding our new rows to the end of the DataTable (the ItemsSource) and then we're using the GridView.SortDescriptors to setup a particular sorting order on the rows.

So, we could start with rows A,B,C and get B1 to add to the DataTable.  This gets added to give A,B,C,B1 and then the SortDescriptor is basically saying order it alphabetically, so visually we get A,B,B1,C.

Could there be a reason why this is affecting it?
0
Chris
Top achievements
Rank 1
answered on 28 Jul 2011, 04:22 PM
Another update on this...

In our code, only to test (it can't work like this in reality), I changed it so that it was always inserting the new DataTable row at a specific index (say index3 when there's 10 records).  With the setting of the SortDescriptors still in the code it still didn't work - the data in the rows past index 3 was still shifting down but the color fade always stayed on the same row - it didn't shift down with the data.

So I then removed the setting of the SortDescriptors and it worked (I can't leave it like this though).  Without the sorting code, the data and the fade shifted down to the next row when one was inserted above.

So I've continued to work on trying to repeat the problem in Pavel's example but can't.  I've added sorting to the example code and I'm always inserting at index 3 but it all still works.

Any idea on where to look now?
0
Chris
Top achievements
Rank 1
answered on 29 Jul 2011, 09:45 AM
This is now resolved.

I suddenly realised I had an 'if' statement wrong and the code was re-setting the SortDescriptors on the GridView every time an update to the underlying DataTable was done.  I've changed it so that the SortDescriptors are only ever done once when the GridView is first populated - everything ok now.  I also managed to then repeat this scenario in the example code.

Hopefully this will be some help to anyone else who makes a similar mistake.
Tags
GridView
Asked by
Chris
Top achievements
Rank 1
Answers by
Ivan Ivanov
Telerik team
Chris
Top achievements
Rank 1
Share this question
or