0

A screen has some RadioButton. When the data context is changed, it's impact the old data context. To reproduce, just create a new WPF project in .NET Framework 4.8.

MainWindow.xaml :

<Window x:Class="WpfApp1.MainWindow"
        ...
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <TextBlock Text="{Binding Name}"/>
        <RadioButton IsChecked="{Binding A}">A</RadioButton>
        <RadioButton IsChecked="{Binding B}">B</RadioButton>
        <Button Click="Button_Click">Switch</Button>
    </StackPanel>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    ViewModel _model1 = new ViewModel { Name = "Model 1", A = true };
    ViewModel _model2 = new ViewModel { Name = "Model 2", B = true };


    public MainWindow()
    {
        InitializeComponent();
        SetDataContext(_model1);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Console.WriteLine("Switch");
        if (DataContext == _model1)
            SetDataContext(_model2);
        else
            SetDataContext(_model1);
    }

    public void SetDataContext(ViewModel model)
    {
        Console.WriteLine($"Set DataContext with {model.Name}");
        DataContext = model;
    }
}

ViewModel.cs

public class ViewModel
{
    public string Name { get; set; }

    private bool _a;
    public bool A
    {
        get
        {
            Console.WriteLine($"{Name} GET A - {_a}");
            return _a;
        }
        set
        {
            Console.WriteLine($"{Name} SET A - {value}");
            _a = value;
        }
    }
    private bool _b;
    public bool B
    {
        get
        {
            Console.WriteLine($"{Name} GET B - {_b}");
            return _b;
        }
        set
        {
            Console.WriteLine($"{Name} SET B - {value}");
            _b = value;
        }
    }
}

Start and click 3 times on the button :

Model 1 SET A - True
Model 2 SET B - True
Set DataContext with Model 1
Model 1 GET A - True
Model 1 GET B - False
Switch
Set DataContext with Model 2
Model 2 GET A - False
Model 2 GET B - True
Switch
Set DataContext with Model 1
Model 1 GET A - True
Model 2 SET B - False     <- Really?
Model 2 GET B - False
Model 1 GET B - False
Switch
Set DataContext with Model 2
Model 2 GET A - False
Model 2 GET B - False

The problem is when the data context is set to the model 1, the model 2 is impacted. I think, it's the first radio button change of value, impact the second radio button that is still bound to the precedent context.

  • Is normal?
  • How avoid this problem?
vernou
  • 6,818
  • 5
  • 30
  • 58
  • `RadioButton`s are tricky. Try the same with `CheckBox` instead. – Sinatr Sep 24 '20 at 11:23
  • It's a minimal example to reproduce the problem. Reproduce the behavior (only one checked) and style with CheckBox, it's weird solution. Maybe a better hack exists. – vernou Sep 24 '20 at 11:49
  • I just tried it with `CheckBox`es myself, works for me, no need for notifications. So `RadioButton` itself is a problem. You can either use a [single property](https://stackoverflow.com/q/37790017/1997232) (you have exactly 2 radio buttons) or again, start with implementing notifications. – Sinatr Sep 24 '20 at 11:58

1 Answers1

1

How avoid this problem?

Set the DataContext to null before you switch:

public void SetDataContext(ViewModel model)
{
    DataContext = null;
    Debug.WriteLine($"Set DataContext with {model.Name}");
    DataContext = model;
}
mm8
  • 163,881
  • 10
  • 57
  • 88