Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

infinite loop when assigning the Thumb of a Track #9904

Open
trebahl opened this issue Oct 7, 2024 · 8 comments · May be fixed by #9934
Open

infinite loop when assigning the Thumb of a Track #9904

trebahl opened this issue Oct 7, 2024 · 8 comments · May be fixed by #9934

Comments

@trebahl
Copy link

trebahl commented Oct 7, 2024

Description

The Track class has a publically settable Thumb property, but I get an infinite loop when I try and set it after the template has been applied.

Reproduction Steps

            var sb = new ScrollBar();
            var w = new Window() { Content = sb };
            w.Show();
            sb.Track.Thumb = new Thumb();

Expected behavior

should return

Actual behavior

infinite loop

Regression?

No response

Known Workarounds

No response

Impact

I'm trying to turn a scrollbar into a range selector. To this end, I want to replace the Thumb by an instance of a derived class that behaves differently when a drag is started near the left or right edge of the thumb. This is why I'm trying to reassign the Thumb of the Track.

Configuration

.net framework 4.8

windows 10 x64

I doubt it is configuration specific as the mistake is easy to spot in the source code, as described in "Other Information", and is generic.

Other information

The problem is in TrackBar.UpdateComponent:

                while (i < 3) 
                {
                    // Array isn't full, break
                    if (_visualChildren[i] == null)
                        break;

                    // found the old value
                    if (_visualChildren[i] == oldValue)
                    {
                        // Move values down until end of array or a null element
                        while (i < 2 && _visualChildren[i + 1] != null)
                        {
                            _visualChildren[i] = _visualChildren[i + 1];
                            i++;
                        }
                    }
                    else
                    {
                        i++;
                    }
                }

oldValue is at position 2 in _visualChildren so that the body of the inner loop is not executed, i is not incremented, and the outer loop never ends.

@himgoyalmicro
Copy link
Contributor

@trebahl Can you please provide a minimal sample repro? And is the app that you are developing is only limited to .NET Framework?

@trebahl
Copy link
Author

trebahl commented Oct 10, 2024

@himgoyalmicro

I did provide a minimal sample: you just have to run the 4 lines of code I included in "Reproduction Steps". I don't understand what more could be needed.

My app is .net framework at the moment, but will be moving to .net in the near future.

But all that is pretty much irrelevant, the mistake in the code I pointed to is blatant and independent of .net vs .net framework.

The fix is also trivial: just using a collection (e.g. List) instead of an array for _visualChildren, and using .Remove instead of duplicating the code of List.

@dotnet-policy-service dotnet-policy-service bot removed the 📭 waiting-author-feedback To request more information from author. label Oct 10, 2024
@h3xds1nz
Copy link
Contributor

h3xds1nz commented Oct 10, 2024

I don't see how using a List<T> or ICollection<T>-based objects over fixed-size array is a better option in this case (or even considered a fix), not mentioning totally diminishing the intent of how many visual children a Track can actually have.

The fix is indeed trivial though not by doing stuff that doesn't make sense.

@trebahl
Copy link
Author

trebahl commented Oct 10, 2024

@h3xds1nz It's a fix because you just have to call .Remove instead of this fragile double loop (as I said "and using .Remove instead of duplicating the code of List."; please read my entire sentence before replying).

@miloush
Copy link
Contributor

miloush commented Oct 10, 2024 via email

@h3xds1nz
Copy link
Contributor

@trebahl Nice tone; I'm really keen on helping you to solve the issue now.

@miloush By the way, looking at the function posted, since you have 3 visual children on Track iirc, replacing anything that's not on i=2 should throw if I'm reading this correctly as you should end up with i=3. I don't have time to run it today but just an observation looking at the proc code.

@trebahl
Copy link
Author

trebahl commented Oct 10, 2024

@h3xds1nz Sorry for getting annoyed, but you started calling me nonsensical even though what I suggested is the correct solution (not duplicating code from the List class).

@trebahl
Copy link
Author

trebahl commented Oct 11, 2024

Thanks for working on it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants