I have a MDI container form, and some child forms that update their title bar texts themselves, independently. After the Text property is changed on the child form, the new title bar text from the child is not updated in the window list menu when the menu is opened. This is the auto-generated window list provided by .NET via the MdiWindowListItem property.
The change only propagates when another event changes the window list physically (opening a new child, closing a child, switching to another child).
Is there a way to force an update of the window list programmatically? I already have some code in place to do menu enabling/disabling at the same time the child's title bar text is changed.
I tried the following with no success:
Update() on the main MenuStrip
Refresh() on the main MenuStrip
Invalidate() on the window MenuStrip
Invalidate() on one of the window list items at runtime
Toggling the Checked state twice on one of the window list items at runtime
There don't seem to be any other remotely viable functions to call on the menu item, its parent ToolStrip, or the parent form that contains the menu system.
The above solution did not work for me. But I followed the link, and found this, which works perfectly:
private void windowMenu_DropDownOpening(object sender, EventArgs e)
{
if (this.ActiveMdiChild != null)
{
Form activeChild = this.ActiveMdiChild;
ActivateMdiChild(null);
ActivateMdiChild(activeChild);
}
}
Thank you!
You need to add a TextChanged event to the child form, with this handler:
private void childForm_TextChanged(object sender, EventArgs e) {
this.ActivateMdiChild( null );
this.ActivateMdiChild( sender as Form );
}
http://social.msdn.microsoft.com/forums/en-US/winforms/thread/a36b89aa-57aa-48b5-87a6-49fbddc9c92d
Instead of activate/deactivate, you can send WM_MDIREFRESHMENU message to the MDI client (not frame) window whenever a window title changed.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644919%28v=VS.85%29.aspx
Related
i'm using a listview to display multiple items to the user. Now I want that the user has the ability to open an detail window with an double click. This works fine but when the window is opened it's immediatly pushed to the background.
I tried several things with the window state etc. the result was in every situation terrible(window is pushed to background or the window is a permanent overlay). The only solution that works relative well is that I change the DoubleClick Event in a MouseLeftButtonUp Event. When a user now click an item the window are in the foreground.
This is my code from the controller class:
public void ShowDetails(object details)
{
Details detailWindow = new Details(this, Config.GetCultureInformation());
detailWindow.LoadData(details);
detailWindow.Show();
}
This my code from the UI Class
private void listViewItem_MouseClick(object sender, MouseButtonEventArgs e)
{
ListViewItem item = sender as ListViewItem;
AppControl.ShowDetails(item.Content);
}
You should show it as modal.
public void ShowDetails(object details)
{
Details detailWindow = new Details(this, Config.GetCultureInformation());
detailWindow.LoadData(details);
detailWindow.ShowDialog(); //Instead of detailWindow.Show();
}
If you want to keep your main window without freeze use detailWindow.BringToFront() or detailWindow.TopMost = true, take a loot at this other post
Source here.
Ok. Thank you for your help and with Topmost I find I way to create a solution that suits for me.
In the constructor of my window I set topmost to true and in the Window is Loaded Event I set topmost to false. My Window is prominent in the foreground but the user can go out of it and can handle things in the main app.
I have a parent window which launches a child window, after doing some selection/operation in the child window is closed and I want to send some info back to the parent window (a custom class object), what's the best way to accomplish this in WPF using the features provided by WPF?
You have many options:
You could use a custom event in your child window that the parent window listens to
You could define a delegate in the child window that references a method in the parent window
You could change the constructor for the child window to take a reference to the parent window and call a method on the parent window using that reference
You could possibly use the VisualTreeHelper class to get the parent window and call a method on that reference
Extracted from this link:
The easiest way I have found to pass data from a child window to a
parent window is to use an application wide property. This property is
an object, and is not the most elegant form to pass data from a child
window to a parent, but it's the least amount of programming. The best
way to do this is using get and set accessor properties.
Create a main window (mainWindow) Create a child window (in this case,
Password)
In the main window, the child window must be shown, say, within a
button click. This window would have a button to do something, in this
case, it's to delete a record from the database.
private void btnDelete_Click(object sender, RoutedEventArgs e)
{
Password passwordentry = new Password();
passwordentry.ShowDialog();
if (Application.Current.Properties["PassGate"].ToString() == "mypassword")
{
Code, or call to delete the record;
}
Application.Current.Properties["PassGate"] = "";
}
In the child window (Password), the property for the application is
set using a textbox. This is a simple window that has a textbox called
PasswordTextBox and a couple of buttons, like Accept and Cancel.
private void AcceptButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.Properties["PassGate"] = PasswordTextBox.Text;
this.Close();
}
I have a windows form app. The main form has a textbox, and a button to launch another form. When the other form is launched, both forms are on screen (but the launched form is modal). The child form has a textbox and button, and when the button is pressed, I want the textbox on the main form (the parent) to be updated with the value in the textbox on the child form.
How is this functionality achieved?
Ideally you want to keep both forms from being dependent on each other, this could be achieved with interfaces:
public interface IMainView
{
public void UpdateValue(string val);
}
public interface IChildView
{
public void Show(IMainView parent);
}
have your main form implement IMainView and the child implement IChildView, the parent calls child.show(this) and the child calls parent.UpdateValue(blah);
Hope this helps.
If the child form is closed when the button is clicked, you could put a public property which wraps the value of the textbox on the child form. Then the main form can read this property after calling ShowDialog.
If you want this to happen without closing the child form, you can create a function on the main form to change the textbox. Then the child form would call that function.
The best ways to achive this situation are clockWize's and Hans Passants's advices.
But what about that?
Write a property for your textbox at parent form, like this.
public string TextBoxText
{
get { return txtTextBox.Text;}
set { txtTextBox.Text = value;}
}
When you are opening the child form set the owner.
ChildForm f = new ChildForm();
f.Owner = this;
f.Show();
Create an event handler to child forms button click event.
public Button1_Click(object sender; EventArgs e)
{
ParentForm f = (ParentForm)this.Owner;
f.TextBoxText = txtChildTextBox.Text;
}
i didn't compile code; so may have errors :)
}
When a button is pressed to close the launched form, returning you to the main form- the launched form's text box is still in scope.
Closing a form is merely changing the object's state, not disposing of it. So in the button eventhandler that launches the form from the main form, the next line after launching your modal window, it can access the text from the object it launched as the textbox is a child of that form's object. Unless you're launching your modal window in another thread, which I wouldn't figure you are since it's modal, when it is closed, it should go to the next line in the buttons eventhandler that launched it.
your main form may have code something like this right now (haven't done winforms in a while so bear with me if I miss something):
public void Button1_Click(object sender, ClickEventArgs e)
{
SomeFormIWantToLaunch launchForm = new SomeFormIWantToLaunch();
launchForm.ShowDialog(this);
}
You need to just add after launchForm.ShowDialog(this); something like:
this.SomeTextBox.Text = launchForm.ATextBox.Text;
Any guidance on the following issue would be greatly appreciated. In which MDIParent event should I disable the items/buttons? Activated? On program Launch, I want the buttons disabled. If there are no active MDIChildren, I want the buttons disabled. When I launch a child form, I want to test that child form for data. If it is a blank form, I want the buttons to remain disabled. I currently have my code in the MdiChildActivated Event Handler. Thanks for your time.
I used the Activate Event to disable all items/buttons. In the MDIChildActive Event I test for a blank form. If not blank, I enable the items/buttons.
I would use MDI Parent form's MdiChildActivate event:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.mdichildactivate.aspx
Please note this remark from that page:
You can use this event to perform tasks such as updating the contents of the MDI child form and changing the menu options available in the MDI parent form based on the status of the MDI child form that is activated.
Also note that this event is also called when a child is closed (from MSDN):
Occurs when a multiple-document interface (MDI) child form is activated or closed within an MDI application.
That means that in this event you could do something like:
menuButton.Enabled = (this.MdiChildren.Length > 0);
or, if you need to check all child forms for some condition, and if one of children needs enabled button then enable the button:
void Form1_MdiChildActivate(object sender, EventArgs e)
{
foreach (Form child in MdiChildren)
{
if (IsToolbarButtonNeededForThisForm(child))
{
toolButton.Enabled = true;
break;
}
}
toolButton.Enabled = false;
I have a dialog-based application.
I need to show a child window like this:
(1) First, the application's main dialog window will show up,
(2) then, a child dialog window will show up automatically on top of that.
You know, it is not enough to call the child window's ShowDialog() in the parent window's constructor or load event. Coz in those cases, the child window will appear first.
What should I do to achieve that?
Use can use the event Shown of your main dialog, to show the child in front of you main dialog. This event is only raised once, when the main dialog is shown the first time. Also you should use the Show() (not ShowDialog) method and then call BringToFront() of your child dialog.
private void OnShown(EventArgs e) {
ChildDialog child = new ChildDialog();
child.Show(this);
child.BringToFront();
}