UserControl does not auto resize with the Form - winforms

I am having troubles with setting my user control to automatically resize with the panel where it is created. When user is resizing a main form that contains the user control, the size of this user control does not change at all making for some poor user experience.
So far I tried following:
Ensure MinimumSize and MaximumSize properties on the user control are set to 0.
Set AutoSize property on both (1) the user control and (2) the panel where it resides to True
Set Anchor property on the panel to Top, Bottom, Left, Right
Set Dock property to Fill for the user control (I did this with the following code)
These attempts had no effect on the behavior of my user control:
CalcUserControl calcControl = new CalcUserControl(CountryId);
calcControl.Dock = DockStyle.Fill;
panelUserCtrl.Controls.Clear();
panelUserCtrl.Controls.Add(calcControl);
Any suggestions would be much appreciated.

Try setting the AutoSize properties to False.
Also, instead of calling Controls.Clear();, try disposing of the controls inside it, something like:
while (panelUserCtrl.Controls.Count > 0) {
panelUserCtrl.Controls[0].Dispose();
}
Otherwise, you are leaking memory since those removed controls would still exist.

You should set AutoSizeMode to GrowAndShrink too.

Related

Can we tab on TabIndex only without TabStop

I have an UI who have a lot of object. I want my tab to circle between some object.
With
KeyboardNavigation.TabIndex="0"
But i don't want to stop on some object without TabIndex.
I know i can use
TabStop="False"
But i have a LOT of objects with children who are user control... Is their a way to say to WPF to only tab stop on item who have a tabindex for a user control?
Is their a way to say to WPF to only tab stop on item who have a tabindex for a user control?
No, because KeyboardNavigation.TabIndex is an attached property that has a default value of Int32.MaxValue unless you set it to something else for a specific element.
So there is no "only items who have a tabindex". You'll have to set the TabStop property to false for all items that you don't want to receive focus using the TAB key.

How to set focus to a default child control unless the user clicks on a different child control?

I have a pretty simple use case but I cannot make it work right. I've got a ListView whose item template is a Note custom UserControl:
Each Note has a few simple controls as shown.
I want this to work so that if a row is selected programmatically or by clicking somewhere in it, it sets focus to the first textbox in that row. But if you click on a control in the row, it activates that control (i.e. lets you edit the Exhibit contents or click the Delete button).
If I don't do anything to set focus, clicking on the row highlights the row but doesn't set focus to any child control.
Within the Note control I have tried this:
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
text.Focus();
}
text is the name of that first TextBox, and it does set focus, but it also does this if I click directly on the Exhibit textbox or Delete button, making them unusable.
So, how can I enable the focusing that I want when the container control gets focus, UNLESS it got that focus via a click on a specific child control (which should then keep the focus)?
After a bit more searching, I found the correct way to implement this: at the root of the container control (the Note UserControl in my case), you can specify the name of the control to be the default focus control:
FocusManager.FocusedElement="{Binding ElementName=text}
Not sure how I missed that one.

How to set focus to UserControl (make it selectable)?

I need to set focus to UserControl itself, not its child.
Otherwise I cannot implement insertion from the buffer. :(
Setting Focusable=True doesn't help.
Google and SO tells only how to set focus to UserControl child.
My control contains:
- Toolbar with several buttons bound to commands of the corresponding
VM
- TextBox which is the input for the filter
- DataGrid - list of items.
I need to bind Ctrl+V command to VM. But to handle this gesture UserControl must have focus within. When there are no items in the grid (VM's collection is empty) buttons are disabled and the only element which can get focus is TextBox. But it handles Ctrl+V in its own way and I don't want to change this behavior.
Thus, I need something to set focus to when I click the area of UserControl.
I believe UserControl is the best candidate for it.
But I don't know how to make it selectable.
The whole problem was in my misunderstanding of controls' behavior.
This SO question clearly shows it I believe.
Thus, setting UserControl.Focusable = true is not sufficient. To make it navigatable via keyboard IsTabStop must be true also. And to make UC selectable by mouse click we should call Focus() in mouse eventhandler. That's it.

Expand Usercontrol to full window size

I am currently working on a project which has a tab control which contains a Wrap panel which contain a series of user controls. I am looking for a way to allow the user to select one user control and maximize it to the size of the tab control/window.
One thought is to simply remove all the other items from the panel.However I am attempting to use MVVM as much as possible and I'm not sure how much the user control should know about the panel. (The user control will contain a button to allow maximizing)
Is there a way to temporarily remove the usercontrol from the grid and treat it like a modal popup or just to fill the window?
How about having "Visible" or "Maximized" bool properties in the view model for each user control based item, and databind said user controls Visibility property to the appropriate property. Then bind your user controls maximize/restore button to command in the view model to change the VM properties appropriately?

Redraw and flicker issues

I have an Outlook style app. So basically I have a sidebar on the left and on the right I have a panel control (pnlMainBody) that hosts content.
The content is typically a user control that I add to the panel when user clicks appropriate button in the side bar. The way I add the user control to the panel is as follows:
// _pnlEmails is the User Control that I am adding to the panel
_pnlEmails = new pnlEmails();
_pnlEmails.Dock = DockStyle.Fill;
this.pnlMainBody.Controls.Add(_pnlEmails);
Some of the user controls that I add to the main panel are quite complex UI-wise. So when this.pnlMainBody.Controls.Add(_pnlEmails); fires, I see the control appear on the screen, then it resizes itself to fill the body of the panel control.
It's quite ugly actually, so I was wondering whether there is a way to not show the resizing until it's actually done resizing?
I've tried setting the user control's .Visible to false. I've tried doing .SuspendLayout, all to no avail.
Is there a way to do this so the screen transitions are smooth?
First try to turn on double buffer painting in the parent form by setting:
this.DoubleBuffered = true;
Do that in your load handler or some such place to see if the flicker goes away.
If that doesn't work you can also try to set the DoubleBuffered property to true for the child controls if they are .NET Control-derived entities. Here's some code that I used recently to get controls that did not expose the double buffer property to paint nicely: (vb version. Do you need C#?)
Private Sub ForceDoubleBuffering(ByVal o As Object)
Dim ctrl As Control
Dim method As Reflection.MethodInfo
Dim flags As Reflection.BindingFlags
ctrl = TryCast(o, Control)
flags = Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic
method = ctrl.GetType().GetMethod("SetStyle", flags)
method.Invoke(ctrl, New Object() {ControlStyles.OptimizedDoubleBuffer, True})
End Sub
I figured out the trick to solving the issue. As I long as I set up the Dock.Fill property after adding the control to the main panel, there is no flicker.
this.pnlMainBody.Controls.Add(_pnlEmails);
_pnlEmails.Dock = DockStyle.Fill;

Resources