Home > Blockchain >  How to change the background color timely depending on the data change in the DataGrid?
How to change the background color timely depending on the data change in the DataGrid?

Time:02-01

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>
  •  Tags:  
  • Related