'Reset all bindings in a WPF application

I have a WPF application that has a lot of text boxes, combo boxes etc. There are two modes:

  1. Fresh
  2. Load existing configurations

If you choose the Fresh mode, you're presented with some default binding values in a "MyConfigs.json" file which is loaded up like this:

public static string currentDirectory = Directory.GetCurrentDirectory();
public static string json = File.ReadAllText(currentDirectory + "/Important/MyConfigs.json");
public static AppMyConfigs Default = JsonConvert.DeserializeObject<AppMyConfigs>(json);

When I start a fresh installation, this MyConfigs.json is used up and it contains a bunch of default values in it which are used to initially fill the text boxes etc with values. Values which do not exist in this are left empty and all of this is alright.

However, I have another mode which allows me to Load existing configurations. In this mode, I can load a .json file which contains all the configurations and then the values in the text boxes etc are replaced with the values in that particular .json file that is loaded up.

My problem right now is that if I load an existing configuration and then go back and select Fresh mode, the values are displayed which were loaded up previously. I would like to have it so that when I choose Fresh mode, it should instead load up the previous values and "reinitialize the bindings".

The XAML of a sample textbox looks something like this:

<StackPanel x:Name="StackName" Orientation="Vertical" Margin="25,25,25,5">
   <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
      <TextBox materialDesign:HintAssist.Hint="Please enter your name*" materialDesign:HintAssist.HintOpacity="10" materialDesign:HintAssist.Background="White" materialDesign:ValidationAssist.Background="White" materialDesign:HintAssist.Foreground="#FF002655" Style="{StaticResource MaterialDesignOutlinedTextFieldTextBox}" x:Name="txtName" Width="230" TextChanged="txtName_TextChanged">
         <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" Source="{StaticResource MyConfigs}" >
            <Binding.ValidationRules>
               <local:TextBoxNotEmptyValidation ValidatesOnTargetUpdated="True"/>
            </Binding.ValidationRules>
         </Binding>
      </TextBox>
   </StackPanel>
</StackPanel>

And the code behind looks like:

private void txtName_TextChanged(object sender, TextChangedEventArgs e)
{
    MyConfigs.GlobalName = txtName.Text;
}

Initially in Fresh mode, the value of MyConfigs.Name is set to John. However, once I load up a different .json file with name like Mark, the name will stay as Mark even after I go to Fresh mode.



Solution 1:[1]

You have to use data binding.

You need to data sources: one for each mode/data view.
Bind the TextBox.Text property to a property on the data source.
According to the current mode, you set the associated data model as the DataContext of the data bindings:

DataModel.cs
The data source for the input form.

class DataModel : INotifyPropertyChanged
{ 
  private string dataField;
  public string DataField
  {
    get => this.dataField;
    set
    {
      this.dataField = value;
      OnPropertyChanged();
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    => this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

MainWindow.xaml.cs

partial class MainWindow : Window
{
  private DataModel FreshData { get; set; }
  private DataModel ExistingData { get; set; }

  public MainWindow()
  {
    InitializeComponent();
  
    // Initialize a new DataModel instance from the default configuration file
    this.FreshData = CreateDataModelFromDefaultConfiguration();

    this.DataContext = this.FreshData;
  }

  private void OnLoadDefaultDataMode_Click(object sender, EventArgs e)
  {
    // Initialize a new DataModel instance from the default configuration file
    this.FreshData = CreateDataModelFromDefaultConfiguration();

    // Update all data bindings
    this.DataContext = this.FreshData;
  }

  private void OnLoadExistingData_Click(object sender, EventArgs e)
  {
    // Initialize a new DataModel instance from an existing configuration file
    this.ExistingData = CreateDataModelFromExistingConfiguration();
    
    // Update all data bindings
    this.DataContext = this.ExistingData;
  }    
}

MainWindow.xaml

<Window>
  <TextBox Text={Binding DataField}" />
</Window>

See Microsoft Docs: Data Binding Overview

If both data models need to implement their individual logic, then create a dedicated data model class for each mode/data view (instead of using two instances of the same type like in this example).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 BionicCode