This is a migrated thread and some comments may be shown as answers.
DataTemplate and DataTrigger in Grid
9 Answers 233 Views
This is a migrated thread and some comments may be shown as answers.
Ian
Top achievements
Rank 1
Ian asked on 29 Mar 2010, 04:35 PM
I am trying to embed a data trigger within a datatemplate attached to the CellTemplate property. The DataTemplate is being applied but the trigger isn't firing (I have a breakpoint set in the isLessThanZero converter and its not being called). I have seen the example of using triggers within a style but I want to have greater control around the items within my data template.

Here's the XAML I am using

                <Controls:GridViewDataColumn Width="100" DataMemberBinding="{Binding Entries[0].Value}" Header="BID" > 
                    <Controls:GridViewDataColumn.CellTemplate> 
                        <DataTemplate> 
                            <Grid> 
                                <Grid.ColumnDefinitions> 
                                    <ColumnDefinition Width="50" /> 
                                    <ColumnDefinition Width="*" /> 
                                </Grid.ColumnDefinitions> 
                                <TextBlock  x:Name="text" Grid.Column="0" Text="{Binding Entries[0].Value}" FontFamily="Tahoma" FontSize="10pt" /> 
                            </Grid> 
 
                            <DataTemplate.Triggers> 
                                <DataTrigger Binding="{Binding Entries[0].Value,Converter={StaticResource isLessThanZero}}" Value="False" > 
                                    <Setter TargetName="text" Property="Background" Value="Red" /> 
                                </DataTrigger> 
                            </DataTemplate.Triggers> 
                              
                        </DataTemplate> 
                    </Controls:GridViewDataColumn.CellTemplate> 
                </Controls:GridViewDataColumn> 

Any suggestions

Ian

9 Answers, 1 is accepted

Sort by
0
Pavel Pavlov
Telerik team
answered on 30 Mar 2010, 01:07 PM
Hi Ian,

Can you please paste  the implementation of your business object ( the one with the entries property) .
So I can try resemble the problem here and provide a solution/workaround.

Regards,
Pavel Pavlov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Ian
Top achievements
Rank 1
answered on 30 Mar 2010, 02:04 PM
Hi Pavel,

Here is the QuoteMessage object (this holds the entries collection). The Merge method is the one which is being used to change the value.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.ComponentModel;  
 
namespace StreamingQuotes.BusinessObject  
{  
    public class QuoteMessage : IEquatable<QuoteMessage>, INotifyPropertyChanged  
    {  
 
        #region INotifyPropertyChanged Members  
        public event PropertyChangedEventHandler PropertyChanged;  
        #endregion  
 
        public QuoteMessage(Quote q)  
        {  
            Quote = q;  
        }  
 
        public Quote Quote { get; set;  }  
 
        private Dictionary<int, QuoteField> entries = new Dictionary<int, QuoteField>();  
        public Dictionary<int, QuoteField> Entries  
        {  
            get { return entries; }  
        }  
 
        public bool Equals(QuoteMessage other)  
        {  
            return Quote.Symbol.Equals(other.Quote.Symbol);  
        }  
 
        public QuoteField this[int index]  
        {  
            get { return entries[index]; }  
        }  
 
 
        public void Add(QuoteField qf)  
        {  
            lock (entries)  
            {  
                if (!entries.ContainsKey(qf.FieldId))  
                    entries.Add(qf.FieldId, qf);  
                else  
                    entries[qf.FieldId] = qf;  
            }  
        }  
 
        public void Merge(QuoteMessage qm)  
        {  
            lock (entries)  
            {  
                foreach (int key in qm.Entries.Keys)  
                    Add(qm.Entries[key]);  
            }  
 
            if ( PropertyChanged != null )  
                PropertyChanged( this, QuoteChangedEventArgs );  
        }  
 
        private static PropertyChangedEventArgs QuoteChangedEventArgs = new PropertyChangedEventArgs("Entries");  
    }  
}  
 


and here is the QuoteField object (each entry in Entries is one of these)

using System;  
using System.Net;  
 
namespace StreamingQuotes.BusinessObject  
{  
    public class QuoteField  
    {  
        public QuoteField( int fieldId, String value )  
        {  
            FieldId = fieldId;  
            Value = value;  
        }  
 
        public int FieldId { get; set; }  
        public String Value { get; set; }  
    }  
}  
 
0
Pavel Pavlov
Telerik team
answered on 01 Apr 2010, 05:15 PM
Hi Ian,

I have built a small project based on your code and started debugging the issue. What I have found is that any triggers in the datatemplate will be ignored due to the way RadGrirdView loads the CellTemplate.
This is something we definitely need to improve for our future versions.
Please excuse us for the inconvenience caused!

Meanwhile the  only workarround I may offer ( in case you need to keep the things inside the datatemplate) is something like :
<telerik:GridViewDataColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="50" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <TextBlock  x:Name="text" Background="{Binding ... Converter={StaticResource ValueToBrushConverter}}" Grid.Column="0" Text="{Binding Entries[0].Value}" FontFamily="Tahoma" FontSize="10pt" />
                            </Grid>
                        </DataTemplate>
                    </telerik:GridViewDataColumn.CellTemplate>
Instead of using a trigger , you may use an IValueConverter which checks the value and returns the appropriate color brush.

Since your post has served as a valuable feedback for us revealing an unknown problem in RadGridView  I am updating your Telerik points.

Sincerely,
Pavel Pavlov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Ian
Top achievements
Rank 1
answered on 01 Apr 2010, 05:24 PM
Thank you for your response Pavel. I was thinking of an IValueConverter for my simple case but maybe I should have started with the thing I'm really trying to do with the grid ;)

What I am trying to do is whenever a cell value changes to paint the foreground text in, say yellow, and after a a brief period, again say 1/2 a second, return the text to black. I was hoping to be able to use a data trigger and attached animation to do this. Any suggestions you have using existing grid functionality? I know I can do this separately by posting the cell updates twice but I was hoping for a simpler solution

Thanks again for your help

Regards

Ian
0
Vlad
Telerik team
answered on 06 Apr 2010, 07:12 AM
Hello Ian,

Please check this blog post for more info about what's coming:
http://blogs.telerik.com/vladimirenchev/posts/10-04-01/conditional_styles_and_templates_with_radgridview_for_silverlight_and_wpf.aspx

Best wishes,
Vlad
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Wenrong
Top achievements
Rank 1
answered on 21 Dec 2012, 04:26 AM
I have met a similar situation as in the OP, however, my case doesn't seem to be able to resolve using a Converter. DataTemplateSelector would solve half of the problem, but when the property value changes, I had to remove and re-insert the item for the template selector to re-apply.

It's been two years since the OP. Is there any plan to make DataTrigger working for CellTemplate?
0
Pavel Pavlov
Telerik team
answered on 21 Dec 2012, 09:11 AM
Hi Wenrong Weng,

In case you need assistance with your scenario can you please describe it in some details . What exactly is your final goal .What specific problems do you meet while implementing it ?

All the best,
Pavel Pavlov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Wenrong
Top achievements
Rank 1
answered on 21 Dec 2012, 09:51 AM
Here's a brief description of what I want to achieve

  • The grid is used to display event list, each event can have one of 3 states
  • Depending on the event state, one grid cell in the row should either have a solid red background, a blinking red background, or transparent background
  • The blinking animation should be all synced instead of each on its own timer

The following is the DataTemplate I've got. blinkerODP is blinking sync source with a dependency property of BlinkOpacity that toggles between 0 and 1 every second, the TimeBackground is the actual blinking object, which should be either transparent (default), solid (when status = 1) or bind to the synced BlinkOpacity (when Status = 0):

<ObjectDataProvider x:Key="blinkerODP"
                    MethodName="GetInstance"
                    ObjectType="{x:Type ui:BlinkAnimationController}"/>
 
<DataTemplate x:Key="eventLogTimeTemplate">
    <Grid>
        <Rectangle x:Name="TimeBackground" Fill="{Binding Priority, Converter={StaticResource priorityToBrushConverter}}" Opacity="0" />
        <TextBlock Text="{Binding OccurrenceTime, Converter={StaticResource utcToLocalTimeConverter}}" Foreground="DarkGray" Margin="7,1,7,1" />
    </Grid>
 
    <DataTemplate.Triggers>
        <!-- Flashing when Inactive or Active -->
        <DataTrigger Binding="{Binding AlarmStack.Status}" Value="0">
            <Setter TargetName="TimeBackground" Property="Opacity" Value="{Binding BlinkOpacity, Source={StaticResource blinkerODP}}" />
        </DataTrigger>
        <!-- Solid color when Active & Acknowledged -->
        <DataTrigger Binding="{Binding AlarmStack.Status}" Value="1">
            <Setter TargetName="TimeBackground" Property="Opacity" Value="1" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>


0
Pavel Pavlov
Telerik team
answered on 21 Dec 2012, 01:16 PM
Hello Wenrong Weng ,

Since this is a complex scenario I would ask you to give me your project ( with the blinkerODP implementation ). I will be glad to debug it and see what prevents it from working correctly .
Once having the runnable project , I  am sure I can think of some solution..

* To be able to attach your project, please open a support ticket , mentioning this thread ID ( 295057).


All the best,
Pavel Pavlov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Asked by
Ian
Top achievements
Rank 1
Answers by
Pavel Pavlov
Telerik team
Ian
Top achievements
Rank 1
Vlad
Telerik team
Wenrong
Top achievements
Rank 1
Share this question
or