How to dynamically change the value of the TextBox if the Binding goes through the Dictionary?

Hello.

A little Preface.
I'm writing an app that works with the CAD system KOMPAS-3D Kompas via Api.
The application processes a package of drawings, filling stamp all drawings immediately via a certain template and saves all drawings in PDF format.

The app has a MainWindow and several Page, each bound to its ViewModel in XAML
<Page.DataContext>
<ViewModels:StampViewModel/>
 </Page.DataContext>


Switch Page using HamburgerMenu.

In Page Stamp.xaml drawn rubber stamp drawing, which has about 60 TextBox to populate and store their values.
5c98f63dac1fa007118350.jpeg

Each cell of a stamp has a particular index in Kompas Api by which it can be written in the drawing.
5c98f78b48e51492122252.png

Now closer to the subject matter.
I have implemented a Singleton which stores the Dictionary I need keys
class StampDictionary
{
 private static StampDictionary instance;

 private Dictionary<string, string> textBoxes;
 public Dictionary<string, string> TextBoxes
{
 get => textBoxes;
set
{
 textBoxes = value;
}
}

 public StampDictionary()
{
ClearDictionary();
}

 public static StampDictionary GetInstance()
{
 if (instance == null)
 instance = new StampDictionary();
 return instance;
}

 public void ClearDictionary()
{
 TextBoxes = new Dictionary<string, string>()

{
{"1",""},{"2",""},{"3",""},{"5",""},{"6",""},{"7",""},{"8",""},{"9",""},
{"10",""},{"19",""},
{"21",""},{"22",""},
{"31",""},{"32",""},
{"110",""},{"111",""},{"112",""},{"113",""},{"114",""},{"115",""},
{"120",""},{"121",""},{"122",""},{"123",""},{"124",""},{"125",""},
{"130",""},{"131",""},{"132",""},{"133",""},{"134",""},{"135",""},
{"140",""},{"141",""},{"142",""},{"143",""},
{"150",""},{"151",""},{"152",""},{"153",""},
{"160",""},{"161",""},{"162",""},{"163",""},
{"170",""},{"171",""},{"172",""},{"173",""},
{"180",""},{"181",""},{"182",""},{"183",""},
{"200",""},{"201",""},{"230",""},{"231",""},
};
}
 }

The Dictionary initially has only the keys to be able to use it via a Binding.

I also have StampViewModel, where the Singleton object and work through it with my Dictionary.
class StampViewModel : ViewModelBase
{
 public ICommand MyCommand { get; set; }

 StampDictionary stampDictionary = StampDictionary.GetInstance();

 public Dictionary<string, string> TextBoxes
{
 get => stampDictionary.TextBoxes;
set
{
 stampDictionary.TextBoxes = value;
}
}

 public StampViewModel()
{
 MyCommand = new Command(ExecuteMethod, CanExecuteMethod);
}

 public bool CanExecuteMethod(object parameter)
{
 return true;
}
 public void ExecuteMethod(object parameter)
{
 switch (parameter)
{
 case "Clear":
stampDictionary.ClearDictionary();
break;
}
}
 }


...and a few lines of XAML
<TextBox Grid.Column="2" Grid.Row="5" Text="{Binding TextBoxes[110], Mode=TwoWay}"/>
<TextBox Grid.Column="3" Grid.Row="5" Text="{Binding TextBoxes[120], Mode=TwoWay}"/>
<TextBox Grid.Column="4" Grid.Row="5" Text="{Binding TextBoxes[130], Mode=TwoWay}"/>


Thus the values of the TextBox bound to values by key from the Dictionary.

In the screenshot above there is also a Clear button that calls the ClearDictionary() and rebuilds the Dictionary again.

So the problem is that the TextBox is not cleared dynamically, but only if you change Page and come back. This can be seen in the GIF below. If the Clear button is not pressed, all the data loaded from singleton, and at the touch of a button, data is removed only after switching between pages.

zd1936ofj7e8tpy1s2svrpijrzu.gif

How to realize this task, so the boxes are cleared dynamically, and generally the approach to treatment 60 boxes? Method more compact than a dictionary, I could not come up.

~~~~~~~~~~
If I may,one more question, which worries me
Why in the Properties of the variable TextBoxes, which is StampViewModel, no need to register PropertyChanged, because in the Properties to change the page without this Binding does not work, and here everything works perfectly.

Binding a variable to a TextBox
public Dictionary<string, string> TextBoxes
{
 get => stampDictionary.TextBoxes;
set
{
 stampDictionary.TextBoxes = value;
//OnPropertyChanged();
}
 }


Variable from the MainViewModel to the Binding Source in the Frame
public string CurrentPage
{
 get => currentPage;
set
{
 currentPage = value;
OnPropertyChanged();
}
 }

<Frame 
Margin="50,0,0,0"
NavigationUIVisibility="Hidden"
 Source="{Binding CurrentPage}">
 </Frame>


Thank you.
March 19th 20 at 08:31
1 answer
March 19th 20 at 08:33
Solution
To inform the view (View) changes the values of specific properties of the VM you need to pass its name as a parameter:

OnPropertyChanged(nameof(TextBoxes));

Directly in the properties you can see that there is a call without parameter passing:

OnPropertyChanged();

The fact that in a typical implementation of the name property is retrieved by using attribute CallerMemberName:

public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string prop = "")
{
// ...
}


It is not necessary to do a set. The property may not be open to the setter or the setter in General. Or if the property is dependent on the other two - for example, to automatically display the sum of values that the user should enter.

In your case with TextBoxes you don't use a setter - it can even be completely removed.
Oh, it became even more clear)
Write more answers, you're doing very well) - houston_Schmidt44 commented on March 19th 20 at 08:36
Thank you :-) - Josue31 commented on March 19th 20 at 08:39

Find more questions by tags XAMLC#WPF