I have it in a DataGrid. Currently I am changing the background color of the row to be Red if the data is greater than 150 then green if less. What I want to do is if the data does not change within 5 seconds after the background color changes, it should turn colorless again. I wasn't sure how to implement this. Can you please help with this?
My Converter
class ChangedDataConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var val = (int)value;
return new SolidColorBrush(val > 150 ? Colors.Red : Colors.Green);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
xaml
<Syncfusion:GridTextColumn DisplayBinding="{Binding ID, Converter={StaticResource IntToHexadecimalConverter}}">
<Syncfusion:GridTextColumn.CellStyle>
<Style TargetType="Syncfusion:GridCell">
<Setter Property="Background" Value="{Binding ID, Converter={StaticResource ChangedDataConverter}}"/>
</Style>
</Syncfusion:GridTextColumn.CellStyle>
</Syncfusion:GridTextColumn>
Edit: I tried the following way. I'm close to what I want, but it only happens once because it has an onl oaded event. I couldn't find which activity I should use. Is there anything like that ?
<Syncfusion:GridTextColumn DisplayBinding="{Binding ID, Converter={StaticResource ByteToHexadecimalConverter}}" Width="100">
<Syncfusion:GridTextColumn.CellStyle>
<Style TargetType="Syncfusion:GridCell">
<Setter Property = "Background" Value="{Binding ID,Converter={StaticResource ChangedDataConverter}}"/>
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(DataGridRow.Background).(SolidColorBrush.Color)"
Duration="00:00:10"
To="Transparent"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Syncfusion:GridTextColumn.CellStyle>
</Syncfusion:GridTextColumn>
CodePudding user response:
Same with using a storyboard:
<DataGrid ItemsSource="{Binding Lines}"
AutoGenerateColumns="False">
<DataGrid.Resources>
<ColorAnimationUsingKeyFrames x:Key="KeyFramesAnimation"
Storyboard.TargetProperty="(DataGridCell.Background).(SolidColorBrush.Color)">
<LinearColorKeyFrame
KeyTime="0:0:0.3"
Value="Red"/>
<LinearColorKeyFrame
KeyTime="0:0:4.7"
Value="Red"/>
<LinearColorKeyFrame
KeyTime="0:0:5"
Value="Green"/>
</ColorAnimationUsingKeyFrames>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ID}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ID, Converter={StaticResource IntToBooleanConverter}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<StaticResource ResourceKey="KeyFramesAnimation"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
Converter:
public class IntToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is int valInt ? valInt > 150 : Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
CodePudding user response:
In the MVVM pattern, it might look like this:
Model:
public class LineModel : INotifyPropertyChanged
{
private int iD;
public int ID
{
get => iD;
set
{
iD = value;
OnPropertyChanged("ID");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string prop = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}
}
ViewModel:
public class ViewModel : INotifyPropertyChanged
{
public Timer Tmr;
private bool timeOut;
public bool TimeOut
{
get => timeOut;
set
{
timeOut = value;
OnPropertyChanged();
}
}
public ObservableCollection<LineModel> Lines { get; set; }
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
TimeOut = false;
}
void LineModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
TimeOut = Lines != null && e.PropertyName == "ID";
Tmr.Enabled = true;
}
public ViewModel()
{
Tmr = new Timer(5000);
Tmr.Elapsed = OnTimedEvent;
Tmr.AutoReset = false;
var line = new LineModel() { ID = 10 };
line.PropertyChanged = LineModel_PropertyChanged;
Lines = new ObservableCollection<LineModel>() { line };
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string prop = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}
}
Converter:
class ChangedDataConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] is int valInt && values[1] is bool valTimeout)
return new SolidColorBrush(valTimeout && valInt > 150 ? Colors.Red : Colors.Green);
else return Binding.DoNothing;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
XAML:
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ID}" Width="300">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource ChangedDataConverter}">
<Binding Path="ID"/>
<Binding RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}" Path="DataContext.TimeOut"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
