AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.9k stars 2.24k forks source link

RadioButton binding is (incorrectly) reset when switching between Tabs or ViewModels #5612

Open joneuhauser opened 3 years ago

joneuhauser commented 3 years ago

Hi,

WPF shows the same behavior (https://stackoverflow.com/questions/8568861/when-viewmodel-is-changed-to-a-different-instance-a-bound-radiobutton-is-reset-t), but I still think this is a bug.

MainWindow.xaml

<Window.DataTemplates>
        <DataTemplate DataType="{x:Type local:TabViewModel}">
            <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
                <RadioButton IsChecked="{Binding !RadioButtonProperty}" Content="Value: false"/>
                <RadioButton IsChecked="{Binding RadioButtonProperty}" Margin="5, 0" Content="Value: true"/>
            </StackPanel>
        </DataTemplate>
    </Window.DataTemplates>
    <TabControl>
        <TabItem Content="{Binding VM1}" Header="Tab 1"></TabItem>
        <TabItem Content="{Binding VM2}" Header="Tab 2"></TabItem>
    </TabControl>

MainWindow.xaml.cs

 public class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }

        private void InitializeComponent()
        {
            AvaloniaXamlLoader.Load(this);
        }
    }
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public class MainWindowViewModel : ViewModelBase
    {
        public TabViewModel VM1 { get; set; }
        public TabViewModel VM2 { get; set; }
        public MainWindowViewModel()
        {
            VM1 = new TabViewModel();
            VM2 = new TabViewModel();
        }
    }
    public class TabViewModel : ViewModelBase
    {
        bool _RadioButtonProperty;

        public bool RadioButtonProperty
        {
            get
            {
                return _RadioButtonProperty;
            }
            set
            {
                if (_RadioButtonProperty == value)
                    return;

                _RadioButtonProperty = value;
                OnPropertyChanged();
            }
        }
    }

Steps to reproduce:

  1. Run app
  2. Switch radio button on the first tab to True
  3. Go to the second tab
  4. Go back to the first tab

Expected outcome: RadioButton in the first tab is still True Observed outcome: RadioButton is reset to False

Not reproduced with a CheckBox.

I don't require Group names to reproduce, so I doubt https://github.com/AvaloniaUI/Avalonia/issues/2717 or https://github.com/AvaloniaUI/Avalonia/issues/2903 are related.

Avalonia 0.9.12 and 0.10.0 on Windows 10 and Ubuntu 20.04

If this is not a bug, how can I work around it?

chkr1011 commented 2 years ago

I have the same issue. This is really annoying.

Is there at least a workaround for this? Probably styling a checkbox to look like a radio button? But this would require implementing the single selection feature.

timunie commented 2 years ago

A styled CheckBox should work. As the property is negated, once you click on first check box, the second should update. But anyway, if you have some time to investigate the issue further, try to clone the latest source and see if you can find a fix for it. Probably the states have to be refreshed just before showing up.