Winforms databinding for invisible controls - winforms

I understand that Databinding in Windows Forms only happens to visible controls.
In my code I have multiple tab pages with several controls bounded to settings in ApplicationSettings. Obviously not all controls are visible when the form is opened. The problem is, that these (hidden) controls actual setting is not updated from ApplicationSettings until the user changes at least one of them.
With this behavior I have trouble checking a control state, I simply can't trust it as it may not reflect the last saved state in ApplicationSettings.
What is the way to ensure all control's state is updated from ApplicationSettings ?
Thank you.

Related

Winforms Databinding and multiple Forms

i have a main window that contains multiple UserControls, arranged as tab pages and tab groups (much like Visual Studio allows to have two or more editors visible at the same time).
I also have the possibility to open such an UserControl into a seperate floating window.
One of these UserControls contains simple form fields (e.g. text boxes). These text boxes are bounded with common databinding to an object / property. The binding mode is OnValidation (not on OnPropertyChanged).
When I switch the focus from this User Control inside the main window into another UserControl in the Main windows, the validation is automatically performed and the databinding is finised / the changed text will be set on the model object / property that is bounded to that text field.
But if I switch the focus to an UserControl which resides in another (floating) window, the databinding is not finished since no validation is performed.
I know that I can handle this manually by triggering ValidateChildren etc, but this seems to my the wrong way / is ugly.
Is there a "correct" / clean way to solve this issue? I want that the validation is performed as soon as the UserControl loses its focus or the window gets deactivated.
One information: On of my UserControls contains a TreeControl. If I edit a tree node label, and when I switch the focus to another (foating) window, the label edit is finished automatically. I want the corresponding behaviour for usual form fields regarding binding...
Thanks for help!
There is no automatic way to do this. From the point of view of the control, it still has the focus (if you click the title bar or Alt-tab back to the main window, you will notice that the focus remains in the same control). Its just that the form the control is on is not active. If you want it to save changes when your form is deactivated, you must manually trigger it. The best way to do that is probably to override the OnDeactivate method of the form.
protected override void OnDeactivate(EventArgs e)
{
base.OnDeactivate(e);
this.ValidateChildren();
}

Inherited control "locked"?

I have a series of forms that are inheriting control from a parent form. To manage space, I am trying to manoeuvre the controls around to make it a better layout on the child forms, however, certain controls appear to be "locked", indicated by a small lock symbol when the control is selected:
I am not sure what is causing this, as it only appears (in this case) to be happening to the labels, but not the text boxes. This is preventing me from editing any of the controls properties, (all of the properties window options have been disabled) meaning that I cannot change their locations. However this is not the case for the text boxes, or the groupboxes they came in.
How can I change this so that I can move them around?
Turns out that this is caused by the modifiers being set to "Private". Setting them to "Public" allows you to move them around on the child form freely.

disable all input controls in a WPF Window

Is there a way to make an entire WPF Window inert after a button click?
The window is invoked via Window.ShowDialog() and after use, the window is no longer needed for interaction but I leave it open to remind the user of the inputs in TextBox's, ListBox's, and give visual feedback via OxyPlot and so on. I leave it to the user to close the window manually.
One solution is to disable all buttons but that's tedious and it still leaves TextBox's functioning. That's not optimal because for anything to be functioning creates the wrong impression that the Window remains for anything other than looking at. It would be better for every control to be non-functioning by a single setting.
I did it by putting a name on the WPF window code behind and then setting .IsEnabled false upon the appropriate button click. All buttons, combo boxes, text boxes, and even OxyPlot became inert at that point and most parts were greyed out.
Consider creating a dedicated boolean dependency property in your code-behind or viewmodel and binding IsEnabled of every TextBox to the property.

How to refresh a WPF subtree without knowing what is in the subtree (Especially all bindings that only depend on converter rather than source value)?

Background:
I use converters to acquire values for most of my binding statement because the bindings are so complicated that even multi-binding cannot satisfy. I have to calculate the value in the converters and return the value. Also I use OneWay or OneTime binding just to show the correct value. When user changes a value, I use Handlers to set the value. The Handlers are also complex program which cannot be simply replaced by TwoWay or OneWayToSource binding. Actually in this case the DataContext does not have any meaning. I use converters. Another reason of using converters is that all Controls are loaded dynamically using many DataTemplates and it's hard to create dynamic DataContext for each Controls in each DataTemplate.
With above background, my application works fine. I'm looking for solutions for our new problem below.
I have many group of Buttons each represent a warehouse containing different type of items.
When double-click a Button, a detail window pops up and user can modify the items. Those items can be represented by CheckBox, Combobox, TextBlocks, TextBox, etc.
For user's convenience, I duplicated some of the frequently-modified Controls from the popup window onto the Button itself (WPF allows Button to contain sub-controls), so that user can directly modify the items without double-click and popup the detail window.
Each Button could contain unknown number of sub-controls such as CheckBox, Combobox, TextBlocks, etc. Here "unknown" means that in the future developer can duplicate any controls onto the Button if the Controls for those items are deemed frequently-modified.
Everything works fine so far.
When user modifies an item in the popup window and closes the window, I used to reload the DataTemplate for the whole window so that everything is refreshed and the controls duplicated onto the Button can synch up with the value modified from inside the popup window.
Everything still works fine so far.
The problem happens when the application runs on machine with slow hardware, where performance is an issue. On a much slower machine, reloading the whole DataTemplate for the whole application that contains many Buttons is quite slow.
So I'm looking for ways to just refresh the Button that is double-clicked, not all Buttons. However, I searched a couple of days and could not find ideal solution of refreshing a WPF sub-tree.
I tried to travel the sub-tree of the Button to assign null to the DataContext property and then assign back the old DataContext, but the binding seems not triggered and the converters were not called.
I saw someone suggested to use something like below:
((ComboBox)sender).GetBindingExpression(ComboBox.ItemsSourceProperty)
.UpdateTarget();
That demands that I know the Control and its property that has bindings. I think I can do the same for all possible Controls and properties but it does not seem a future-proof solution.
Anybody knows an effective way of refreshing a WPF sub-tree without knowing what is in the sub-tree?

Weird two controls / same datasource problem

This is using winforms.
I have a listbox and a combo box, both tied to the same datasource, same display members, same value members. All is bound just fine and the items show up in both the controls.
The problem is when I change a selection in one control, it moves to the same index in the other control. I don't have any events tied to either control. It is just happening on its own. Has anyone ever run into this?
This is because both the controls share the same BindingContext/CurrencyManager. Controls inherit the BindingContext from their container control. A BindingContext maintains only one CurrencyManager per DataSource. If you want to have two different CurrencyManagers, you need to have two BindingContexts.
So when once of the controls selection is changed, currencyManagaer.Current gets updated. This affects all the controls that share the same DataSource.
Instantiate a new BindingContext and assign it to the BindingContext property of one of the ComboBoxes:
comboBox2.BindingContext = new BindingContext();
This should solve the problem.
The datasource is a separate object. When one of the controls changes the datasource active row it sends out an update notification to the other controls to move accordingly. This is normal and expected behavior.
The idea behind it is to simplify navigating record sets while keeping all the bound controls in sync.
If you don't want that, use two datasources tied to the same underlying data.
I think that might be intended to be a feature. For Master/Detail type forms.

Resources