Data bindings don't change UI harmoniously after await Task.Delay(..)

43 Views Asked by At

I have 2 seperate data bindings, these 2 variables fill 2 seperate group of circles on the screen.

public ObservableCollection<Color> CircleColors
{
    get => _circleColors;
    set
    {
        _circleColors = value;
        OnPropertyChanged(nameof(CircleColors));
    }
}
public ObservableCollection<CircleViewModel> SolutionColors
{
    get => _solutionColors;
    set
    {
        _solutionColors = value;
        OnPropertyChanged(nameof(SolutionColors));
    }
}
<CollectionView ItemsSource="{Binding CircleColors}" SelectionMode="None">
<CollectionView ItemsSource="{Binding SolutionColors}" 

Circle Colors are 3 rows of 3 circles or 4 rows of 4 circles (depending on the variable NumberOfCircles). Solution Colors are either 3 circles or 4 circles too. Please see this image: The look of circles

When a certain result is achieved by the user

public bool IsSolutionAchieved
{
    get => _isSolutionAchieved;
    set
    {
        if (value)
        {
            Animate();
        }
         
        _isSolutionAchieved = value;
        OnPropertyChanged(nameof(IsSolutionAchieved));
    }
} 

will be set to true and the all circles will light up and change colors in a happy fashion one row after the other basically. So when animation round is 1, row1 (all 3 circles) will get red. After 300ms row2 will get red, and row1 will turn blue. etc. And when the first round completes they will alternate between colors. That's what the Animate function is for. The rows are just gonna change colors for a few seconds one row after the other including Solution Colors, which is a another row and the actor of second databinding above.

private async void Animate()
{
    int repetitions = 15;
    List<Color> cTemp;

    List<Color> copySolution = new();
    for (int i = 0; i < _solutionColors.Count; i++)
        copySolution.Add(_solutionColors[i].Color);

    List<Color> copyRows = new List<Color>(_circleColors);
    List<Color> happyColorList = new List<Color>
    {
        Color.FromRgb(255, 0, 0),
        Color.FromRgb(0, 0, 255),
        Color.FromRgb(0, 255, 0),
        Color.FromRgb(255, 255, 0),
    };
    if (_numberOfCircles == 4) happyColorList.Add(Color.FromRgb(255, 0, 255));

    for (int i = 0; i < repetitions; i++)
    {
        int rowCountToBeAnimated = animationRound <= _numberOfCircles ? animationRound + 1 : _numberOfCircles + 1;
        cTemp = new(_circleColors);

        for (int j = 0; j < rowCountToBeAnimated; j++)
        {
            AnimateRow(j, happyColorList, cTemp);
        }

        animationRound++;

        await Task.Delay(300);
    }

    for (int i = 0; i < _circleColors.Count; i++)
        _circleColors[i] = copyRows[i];

    for (int i = 0; i < _solutionColors.Count; i++)
        _solutionColors[i].Color = copySolution[i];

    _tick1.IsVisible = _tick2.IsVisible = true;
}

One row after the other they will go from red to yellow to blue etc. after waiting 0.3 seconds. This will continue for a certain number of times as determined by this function above.

private void AnimateRow(int row, List<Color> happyColorList, List<Color> cTemp)
{
    for (int i = 0; i < _numberOfCircles; i++)
    {
        if (animationRound <= _numberOfCircles) 
        {
            if (row < _numberOfCircles)
                _circleColors[row * _numberOfCircles + i] = happyColorList[animationRound - row];
            else
                _solutionColors[i].Color = happyColorList[0];
        }
        else
        {
            if (row == 0)
                _circleColors[i] = _solutionColors[0].Color;
            else if (row == _numberOfCircles)
                _solutionColors[i].Color = cTemp[(row - 1) * _numberOfCircles];
            else
                _circleColors[row * _numberOfCircles + i] = cTemp[(row - 1)*_numberOfCircles];
        }
    }
}

The thing is the two bindings don't affect UI in harmony. The circles in the solution row (last row) don't wait for 300ms for the previous row to change as they should. What is worse (and probably for the same reason) solution colors row (last row in the image) always seem to have the same color as the previous row. When I change 300 ms to 3000 ms for example, well then I can see the last row -the solution row- to have a different happy color than the previous row but still the time interval you see is not the same and not in harmony as the rows above it. But at least I can see it have a different happy color from the previous row.

The assignments are made right after each other in the function

AnimateRow()

and then the delay runs for all in

Animate()

but the rhythm is not right with the last row.(The solution row)

Thank you, and please allow me to further clarify if it looks chaotic.

0

There are 0 best solutions below