Force a usercontrol on web page to reinitialize iteself - c#

There are 2 user controls, one is inside the other.
These controls are located on an .aspx.
One control is a modal popup the other is a custom search control (the search control is inside the modal popup).
After a user has completed a search and closes the form, the next time the popup opens (for the same user) the old values are still present.
How can I clear the values out each time the form loads?
Edit:
Is it possible to capture the popup closing event?

You could clear all the values using javascript- here is an example using jquery:
http://beckelman.net/post/2008/09/24/Clear-Input-Fields-in-an-AjaxControlToolkit-ModalPopup-When-Cancel-is-Clicked.aspx

For one of the applications I currently maintain we use a recursive function to reset all the fields within the control. I have added it below but remember it is used in a C# windows application not a web application. Hope it helps.
public static void ResetFields(Control.ControlCollection pageControls)
{
foreach (Control contl in pageControls)
{
var strCntName = (contl.GetType()).Name;
switch (strCntName)
{
case "Button":
contl.Enabled = true;
break;
case "TextBox":
var txtSource = (TextBox)contl;
txtSource.Text = "";
break;
case "ListBox":
var lstSource = (ListBox)contl;
lstSource.SelectedIndex = -1;
lstSource.Enabled = true;
break;
case "ComboBox":
var cmbSource = (ComboBox)contl;
cmbSource.SelectedIndex = -1;
cmbSource.Enabled = true;
break;
case "DataGridView":
var dgvSource = (DataGridView)contl;
dgvSource.Rows.Clear();
break;
case "CheckBox":
var chkSource = (CheckBox)contl;
chkSource.Checked = false;
chkSource.Enabled = true;
break;
}
ResetFields(contl.Controls);
}
}

As it turns out there is no method on the control to clear out the values on the control.
So what I have to do is create the method on the search control to clear out the control and create a method on the popup control to capture the popup open or close event to trigger the clear method.
At first I wasn't going to be able to change the control..since explaining that this was the only way to solve the issue the control can be changed..thank god! And since the method is not going to be a default option it won't affect anywhere else the controls are used.

Assuming this user control has some client side JS code associated with it, I would modify the control to clear out its search values and results upon closing the modal popup.
This will ensure when the modal popup is reopened its in the correct state for new searches.
Sys.Application.add_init wouldn't work in this case since that will only run once when the page is loaded.
You need to write some new JS when the model popup is cancelled or closed.
Modifying the control will be your best option here so all other pages that use this control can take advantage of the new reset functionality.
It's difficult to give you any more specific information at this time without knowing the structure of your page, usercontrol and any existing javascript.

Related

Sending parameters to a control user from a form c#,visual Studio

I am trying to use a function of my control user from my main form, my code is the next:
chatbox bbl = new bunifchat.chatbox();
bbl.sendmessage("a");
chatbox is my control user and i am trying to user the function sendmessage sending a string but nothing happens.
This is the function in my control user:
public void sendmessage(String message)
{
bubble bbl = new bunifchat.bubble(message);//this is another control user
bbl.Location = bubble1.Location;
bbl.Size = bubble1.Size;
bbl.Anchor = bubble1.Anchor;
bbl.Top = bbl_old.Bottom + 10;
panel2.Controls.Add(bbl);
panel2.VerticalScroll.Value = panel2.VerticalScroll.Maximum;
bbl_old = bbl;
}
First of all you need to make sure you are using the right control.
chatbox bbl = new bunifchat.chatbox();
bbl.sendmessage("a");
This will create a new chatbox object and call a method on it. But unless this actual object is added to the Controls of your main form it is not part of the UI and nothing will happen. You probably want to add the Chatbox control to your form in the designer, give it a name, and just call the method on that object:
myChatbox.sendmessage("a");
Second problem is that your send method tries to emulate a list with by docking individual controls. This will probably cause problems. A better solution would be to use a listView.
Third problem is that sendmessage does not invalidate the control. This is sometimes needed to make sure windows redraws the control with the latest updates. It is possible this is done implicitly by Control.Add, but whenever there is something not showing updates I usually add a invalidate call and check if that solves the problem (and remove it if it does not solve the problem).

Show MdiChild on top of all other MdiChildren

Does anyone know about Multiple Document Interfaces in C#? I'm having trouble with Form.Show(this) to keep one of the child forms perpetually on top of the rest. If the form already has an owner (set to MdiParent), then the program throws an exception when calling the show method.
Here's a switch case that's supposed to create and display a child form, but errors out due to the problem stated above. Are there any alternatives to this to keep the form on top of all the others?
case Page.Call:
if (call == null)
{
call = new CallForm();
call.MdiParent = this;
call.Dock = DockStyle.Fill;
}
call.Show(this);
break;

Programmatically changing form controls

I'm not sure if this can be done but I'd like to know if it is possible to completely alter what controls are on the form programmatically, similar to what happens with installers; when you click the next button the form doesn't hide or close and open the next form, it mearly loads a different set of controls(at least, that's how it appears).
Is it possible to do this with C# in Visual Studio? Or do you have to use tabs or hidden panels?
I think what you're looking for is UserControl. A UserControl is like a form in the way you can use it as a container for other controls.
You can find a walkthrough here.
In the case of installers you mentioned or wizards in general you can design a different UserControl for each step and load each of them in a reserved area in the form. The reserved area can be a panel.
for example assume you have a button which calls a method with wizards step number as parameter:
UserControl _step1Control = new UcStep1Control;
UserControl _step2Control = new UcStep2Control;
private void SetStep(int stepNumber)
{
panel1.Controls.Clear();
switch(stepNumber)
{
case 1:
panel.Controls.Add(_step1Control);
break;
case 2:
panel1.Controls.Add(_step2Control);
break;
default:
break;
}
}
Yes you can do anything to the controls programatically. The designer that you use also generates C# code in the background.
In order to add a new control to your form, you use the the Form.Controls.Add(Control c) method. Any class which inherits from Control (Button, ListBox, etc) can be used. To remove it, you use the Remove method instead of Add.

Webbrowser steals focus

I'm using webbrowser control in my winforms app (c#). And when it is doing automation things, I'm losing focus control from the window I was working with. Webbrowsers' form doesn't show up also, I just lose focus from the contol. I now writing this message I have to click into textbox again and again...
How to disable such behaviour in webbrowser?
I create invisible webbrowser like that:
var br = new WebBrowser();
br.Visible = false;
br.ScriptErrorsSuppressed = true;
Please advise.
I had the same problem:
The Webbrowser Control stole focus from the application once the URL is loaded.
This worked for me:
Before Webbrowser.Navigate() method call, set the parent control of the Webbrowser to Enabled = false.
At the DocumentCompleted event of the Webbrowser, reset parent control of the Webbrowser to Enabled = true.
You can't do it directly on Webbrowser because WebBrowserBase.Enabled is not supported.
Let me know if it works for you.
You could try disabling it globally via the SystemParametersInfo api. Use SPI_SETFOREGROUNDLOCKTIMEOUT. Setting foreground lockout is a global settings, so you will want to clear this setting when you're done. A more permanent solution is to change HKCU\Control Panel\Desktop\ForegroundLockTimeout registry key. See also this discussion on social.msdn (specifically, billb08's answer).
I guess WebBrowser acquires the focus after a page is loaded by calling Navigate (or the Click method of an HtmlElement, which causes navigation). The focus could be given back to the control on the window (the TextBox) in the DocumentComplete event handler of the WebBrowser, but this is very difficult:
When would you determine which control owned the focus
originally? Before calling Navigate? This is not enough, because the
user can move to another control after calling Navigate, but before
handling DocumentComplete.
AFAIK setting the focus to a TextBox will select its whole
content, so you will have to put the cursor back to its original
position. But when would you store the original position? Same problem.
There can be more than one DocumentComplete event after a single
Navigate (or Click).
A possible solution would be to create a separate application for your hidden WebBrowser. This second application would be invisible, and could communicate with the original GUI application using some InterProcess Communication (IPC) technique. Because the WebBrowser in this case would run in a different process, you would have a better chance not to lose lose the focus and bother the user.
it's a very complex problem to fix, and should be revised by microsoft, an app just stealing the focus is not logical, it does depend on what the website is doing though. I had to resort to a CBT filter, see http://msdn.microsoft.com/en-us/magazine/cc188966.aspx, and filter out unwanted HCBT_ACTIVATE and HCBT_SETFOCUS (return 1;). You can use GetWindowClass(wParam) to see what's going on.
Even above didn't entirely work, the app window would still pop to the front temporarily so worked around that using SetWindowPos HWND_TOPMOST and HWND_NOTOPMOST on the window currently in foreground. The HCBT_SETFOCUS gets hit 2 or 3 times so on 1st set HWND_TOPMOST and last set HWND_NOTOPMOST. Count how many classname == "Internet Explorer_Server" which should be 2 (or possibly depends on website?), the other is "Shell Embedding" but doesn't always occur. Hope it helps.
I was looking at all the other answers to this question and they weren't working for me, but i saw the one about settings Browser.Parent.Enabled = false; i tried so and got an error, so i tried this instead it just came to mind.
Browser.Parent = new Control();
Browser.Parent.Enabled = false;
And now the problem is completely gone, it does not take away focus anymore.
I am using the web browser class as a variable, it is not on my form.
well this worked for me try it, this seemed to be a 100% solution.
Most of the methods won't work for me on more than one web browser. This method is work with any amount of web browsers;
1. Put web browser into a panel and set panel enabled to false, then navigate;
webBrowser.Parent = panelBottom;
panelWebBrowser.Enabled = false;
webBrowser.Navigate("http://www.google.com");
2. Define a navigated event to web browser and delay panels enabling for a second;
private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
System.Threading.Timer timer = null;
timer = new System.Threading.Timer((obj) =>
{
panelWebBrowser.Enabled = true;
timer.Dispose();
},null, 1000, Timeout.Infinite);
}
My solution for sending the focus back to a form:
Private Sub Web_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles Web.DocumentCompleted
If Me.Visible = False Then
For Each f As Form In My.Application.OpenForms
If TypeOf f Is frmLogin Then
Dim fl As frmLogin = DirectCast(f, frmLogin)
If fl.Visible = True Then
fl.Focus()
Exit For
End If
End If
Next
End If
End Sub

How can I transfer information to another form without using static forms?

I have a Windows form that's generated using code (including buttons and what not). On it, amongst other things, there is a text box and a button. Clicking the button opens a new Windows form which resembles an Outlook contact list. It's basically a data grid view with a few options for filtering. The idea is that the user selects a row in this home-made contact book and hits a button. After hitting that button, the (second) form should close and the email address the user selects should be displayed in the text box on the first form.
I cannot use static forms for this purpose, so is there any way to let the first form know the user has selected something on the second firm? Can you do this with events, or is there another way? Mind that I hardly know anything about delegates and forms yet.
Please advise.
Edit 1 = SOLVED
I can return the email address from the second form to the first form now, but that brings me to another question. I am generating controls and in that process I'm also generating the MouseClick eventhandler, in which the previous procedure for selecting a contact is put.
But how do I, after returning the email address in the MouseClick eventhandler, insert that information into a generated text box? Code to illustrate:
btn.MouseClick += new MouseEventHandler(btn_MouseClick);
That line is put somewhere in the GenerateControls() method.
void btnContacts_MouseClick(object sender, MouseEventArgs e)
{
using (frmContactList f = new frmContactList())
{
if (f.ShowDialog(fPrompt) == DialogResult.Cancel)
{
var address = f.ContactItem;
MessageBox.Show(address.Email1Address.ToString());
}
}
}
That appears separately in the class. So how do I put the email address into a text box I previously generated?
Forms in .Net are normal classes that inherit from a Form class.
You should add a property to the second (popup) form that gets the selected email address.
You should show the popup by calling ShowDialog.
This is a blocking call that will show the second form as a modal dialog.
The call only finishes after the second form closes, so the next line of code will run after the user closes the popup.
You can then check the property in the second form to find out what the user selected.
For example: (In the first form)
using(ContactSelector popup = new ContactSelector(...)) {
if (popup.ShowDialog(this) == DialogResult.Cancel)
return;
var selectedAddress = popup.SelectedAddress;
//Do something
}
In response to my first edit, this is how I solved it. If anyone knows how to make it more elegant, please let me know.
void btnContacts_MouseClick(object sender, MouseEventArgs e)
{
using (frmContactList f = new frmContactList())
{
if (f.ShowDialog(fPrompt) == DialogResult.Cancel)
{
var contact = f.ContactItem;
TextBox tbx = ((Button)sender).Parent.Controls[0] as TextBox;
tbx.Text = contact.Email1Address;
}
}
}
You should keep a reference to your generated TextBox in a variable (private field in your class) and use this instead of looking it up in the Controls array. This way your code would still work even if you some time in the future change the location it has in the array, and you would get a compiler message if you removed that field, but forgot to remove the code that used it.
If the second form is modal, I would recommend that rather than having the first form create an instance of the second form and use ShowModal on it, you should have a Shared/static function in the second form's class which will create an instance of the second form, ShowModal it, copy the appropriate data somewhere, dispose the form, and finally return the appropriate data. If you use that approach, make the second form's constructor Protected, since the form should only be created using the shared function.

Categories