microsoft / microsoft-ui-xaml

WinUI: a modern UI framework with a rich set of controls and styles to build dynamic and high-performing Windows applications.
MIT License
6.37k stars 682 forks source link

ListView of NumberBox with Minimum constraint corrupts value when ordered #10182

Open yasar11732 opened 3 days ago

yasar11732 commented 3 days ago

Describe the bug

ListView can change values of underlying data if it contains NumberBox with Minimum constraint. It is possible to assume this extends to other inputs with contraints as well.

Steps to reproduce the bug

MainWindow.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<Window
    x:Class="NumberboxText.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:NumberboxText"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="NumberboxText"
    mc:Ignorable="d">
    <StackPanel Orientation="Vertical">
        <Button Click="Button_Click">Sort</Button>
        <ListView ItemsSource="{x:Bind Items}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:TestItem">
                    <NumberBox
                    Value="{x:Bind Current, Mode=TwoWay}"
                    Minimum="{x:Bind Min}"
                />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>

</Window>

MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Capture.Frames;

namespace NumberboxText;

public class TestItem : INotifyPropertyChanged
{
    private int _order;
    private int _min;
    private int _current;

    public event PropertyChangedEventHandler? PropertyChanged;

    public int Order
    {
        get => _order;
        set => SetProperty(ref _order, value);
    }

    public int Min
    {
        get => _min;
        set => SetProperty(ref _min, value);
    }

    public int Current
    {
        get => _current;
        set => SetProperty(ref _current, value);
    }

    protected void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        field = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

}
public sealed partial class MainWindow : Window
{
    public readonly ObservableCollection<TestItem> Items = [];
    public MainWindow()
    {
        this.InitializeComponent();
        Items.Add(new TestItem { Order = 3, Min = 3, Current = 3 });
        Items.Add(new TestItem { Order = 1, Min = 1, Current = 1 });
        Items.Add(new TestItem { Order = 4, Min = 4, Current = 4 });
        Items.Add(new TestItem { Order = 2, Min = 2, Current = 2 });

    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        for (var i = Items.Count - 1; i >= 0; i--)
        {
            for (var j = 1; j <= i; j++)
            {
                if (Items[j - 1].Order > Items[j].Order)
                {
                    Items.Move(j - 1, j);
                }
            }
        }
    }
}

Expected behavior

Ordering items inside ListView should not cause values to change.

Screenshots

Image

NuGet package version

None

Windows version

No response

Additional context

Cross-Post from: https://stackoverflow.com/questions/79203554/listview-of-numberbox-with-minimum-constraint-corrupts-value-when-ordered

Replacing whole collection with new, sorted list also causes this behaviour to happen.

AndrewKeepCoding commented 1 day ago

NumberBox seems not be resetting when given a new data context. Here's a reproducible repo.

Similar behavior can be seen by adding several items to the list above, and just scrolling through the items.

yasar11732 commented 1 day ago

Based on @AndrewKeepCoding 's comment, I could reproduce the problem outside of a ListView. Problem seems to about how NumberBox handles a change in binding. Here is the repo