I have a print dialogue that is triggered from the a button on the binding navigator toolstrip and to give the print dialogue box focus I have created a delegate. My question is how do you trigger the print if dialogue result ok?
This is my code...
delegate DialogResult ShowPrintDialogue();
private void trackPrint_Click(object sender, EventArgs e)
{
PrintDocument docToPrint = new PrintDocument();
trackPrintDialog.AllowSomePages = true;
trackPrintDialog.Document = docToPrint;
docToPrint.DefaultPageSettings.Landscape = true;
docToPrint.DocumentName = "Track";
ShowPrintDialogue spd = new ShowPrintDialogue(trackPrintDialog.ShowDialog);
this.BeginInvoke(spd);
if (spd() == DialogResult.OK) // Doesn't work...
{
docToPrint.PrintPage += new PrintPageEventHandler(PrintImage);
docToPrint.Print();
}
}
I'm not exactly sure why you would want to do this. Calling trackPrintDialog.ShowDialog() should show the print dialog and focus it for user interaction. It should also prevent controls beneath the dialog from being changed.
Calling .BeginInvoke means you're calling an asynchronous section of code, meaning it immediately returns and continues to run the code after it. What that means is that since the user isn't, almost instantaneously, clicking OK on the print dialog, the if-statement evaluates spd() to be None and nothing will print.
The PrintDialog is intended to be blocking, so using a delegate to show and focus the print dialog should not done.
Related
When I show a MessageBox with helpFilePath set to some url, the url loads multiple times. It seems to me that the url loads a number of times equal to the number of my forms parents plus one.
Can anyone explain why this is happening?
According to MSDN the HelpRequested event will fire on the active form:
When the user clicks Help button, the Help file specified in the
helpFilePath parameter is opened. The form that owns the message box
(or the active form) also receives the HelpRequested event.
The helpFilePath parameter can be of the form C:\path\sample.chm
or /folder/file.htm.
But I don't understand why raising the HelpRequested event on the parent forms should load the link from the child forms MessageBox.
Am I doing something I'm not supposed to?
This code will reproduce the behaviour:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// First button spawns new instances of the form
var button1 = new Button { Text = "New Form" };
Controls.Add(button1);
button1.Click += delegate
{
using (var form = new Form1())
form.ShowDialog();
};
// Second button shows the MessageBox with the help-button
var button2 = new Button { Text = "Dialog", Left = button1.Right };
Controls.Add(button2);
button2.Click += delegate
{
MessageBox.Show(
"Press Help",
"Caption",
MessageBoxButtons.OK,
MessageBoxIcon.None,
MessageBoxDefaultButton.Button1,
0, // Default MessageBoxOption (probably not related to the behaviour)
"http://SomeHelpSite.com/MyOnlineHelp.htm");
};
}
}
Click "New Form" a couple of times:
Then click "Dialog":
Now, click the help-button:
On my computer this opens SomeHelpSite.com tree times:
I have found a way to block the undesidered behavior and, probably, an explanation why this happens.
To block the opening of undesidered url after the first one you need to simply add an handler for the HelpRequested event. In this event you should inform the WinForms engine that you have handled the help request and no further action is required
public Form1()
{
InitializeComponent();
this.HelpRequested += onHelpRequested;
.....
}
protected void onHelpRequested(object sender, HelpEventArgs e)
{
e.Handled = true;
}
In this way, only one page is opened.
Now the explanation why this happens is, probably, reported at the MSDN page for the Handled property of the HelpEventArgs where you could find this statement:
If you do not set this property to true the event will be passed to
Windows for additional processing.
EDIT Further tests shows that also without setting the Handled property to true, the simple fact that an event handler for the HelpRequested event exists stops the undesidered behavior
I have a WPF Application consisting of a MainWindow which also has a regular button inside.
Bound to the button click event I am loading a serialized object via OpenFileDialog:
private void LoadNetwork_Click(object sender, RoutedEventArgs e)
{
var openDialog = new OpenFileDialog { Multiselect = false };
var result = openDialog.ShowDialog();
if (result)
{
string file = openDialog.FileName;
try
{
_network= new SimplifiedNetwork(file, 1);
MessageBox.Show("Loaded OK");
}
catch (Exception)
{
MessageBox.Show("Load error");
}
}
}
After this method gets executed the UI doesn't update anymore. And when I say nothing, I mean not even the hover effects on the buttons in the Window work (not to mention updating labels via code behind, property changed events, begin invokes etc.), it's like it's frozen (but still responsive to clicks).
I thought it was something I did inside my routines, but simply reducing the method call to
private void LoadNetwork_Click(object sender, RoutedEventArgs e)
{
var openDialog = new OpenFileDialog { Multiselect = false };
var result = openDialog.ShowDialog();
}
has the same result.
Clarification.
-This occurs with after the Modal dialog is closed.
-It also seems to manifest itself as soon as the UI loses focus for any reason (like minimize - restore, switch to another window).
-This seems to occur only on my Windows 8.1 machine (put in an xp VM I have around, is OK).
Any ideas?
The OpenFileDialog is a modal dialog, it is intended that the window in the background is not responding when the dialog is open.
Here is more information and also a possible solution to your problem.
Please help, I am trying to make program as soon as it opens to prompt with window to save rtf file, I try to use Window_Activated event but when programs starts, it does open window to save as but it doesn't matter if i press on Save or Cancel, the SaveFileDialog keeps showing up in loop and can not get pass that. This is code I used but maybe is not even good.
private void Window_Activated(object sender, EventArgs e)
{
Microsoft.Win32.SaveFileDialog saveDlg = new Microsoft.Win32.SaveFileDialog();
saveDlg.DefaultExt = ".rtf";
saveDlg.Filter = "RTF Documents (.rtf)|*rtf";
Nullable<bool> rezultat = saveDlg.ShowDialog();
if (rezultat == true)
{
string filename = saveDlg.FileName;
System.IO.File.Create(filename);
}
}
Do it like this
*> NOTE: this will used goto statement where other may argued not to
used it but it is still supported and must only be used if no other
options*
private void Window_Load(object sender, EventArgs e)
{
System.Windows.Forms.SaveFileDialog saveDlg = new System.Windows.Forms.SaveFileDialog();
saveDlg.DefaultExt = ".rtf";
saveDlg.Filter = "RTF Documents (.rtf)|*rtf";
RetHere:
if (saveDlg.ShowDialog() == System.Windows.Forms.DialogResult.Yes)
{
string filename = saveDlg.FileName;
System.IO.File.Create(filename);
}
else {
System.Windows.Forms.MessageBox.Show("Your message here!", "Save", System.Windows.Forms.MessageBoxButtons.OK);
goto RetHere;
}
}
Window activated occurs when it becomes the foreground window, when you prompt the user to save, it changes focus, on clicking OK or CANCEL it changes back the focus to the main window, firing up the Window_Activated event. Could this be an infinite loop? I didn't test it but I guess it could happen.
Edit: I would suggest yout to use another event, maybe when the form loads?
You can't use Window_Activated for this (clearly). It's fired every time the window is activated. Here's what's happening:
Your app starts.
Window_Activated is executed.
You display the saveDlg, which deactivates your window.
The saveDlg closes, which activates your window.
Go to step #2
You need to either add a flag that is set the first time Window_Activated is executed, and check for it before executing the code, or use a different event that only runs once (like Load).
I'm creating a custom task panel for an Excel Add-In using VS 2010. I want the task pane to always be visible to the user, so it can't be closed, moved, or resized.
Is there a way to disable those capabilities in the task pane's title bar? Perhaps by disabling the close box and the down arrow button in the upper right corner?
Thanks
To stop a custom task pane from being closed:
When a user presses the close button, the result is that the custom pane's Visible property is set to false. This causes the custom pane's VisibleChanged event to fire. Within that event's handler, you can forcibly reopen the custom task pane.
private static void OnVisibleChanged(object sender, EventArgs e)
{
var customTaskPane = sender as CustomTaskPane;
if (customTaskPane != null)
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => { customTaskPane.Visible = true; }));
}
}
Note that I'm using the Dispatcher's BeginInvoke method. This is because if you try to directly set the custom pane's Visible property to true, without using the Dispatcher, an exception is thrown since that isn't allowed within the event handler. Using the BeginInvoke method causes the assignment to execute asynchronously, thus working around that limitation.
To stop a custom task pane from being resized:
To accomplish this, you need to attach a SizeChanged event handler to the custom task pane's UserControl. For example:
var sampleHostControl = new WpfHostControl(Globals.AddIn.SamplePaneWpfControl);
_samplePane = this.CustomTaskPanes.Add(sampleHostControl, "Sample");
sampleHostControl.SizeChanged += new EventHandler(OnHostControlSizeChanged);
Inside the event handler, you can reset the _samplePane's height.
private const int PaneHeight = 52;
private void OnHostControlSizeChanged(object sender, EventArgs e)
{
if (_samplePane != null && _samplePane.Height != PaneHeight)
{
System.Windows.Forms.SendKeys.Send("{ESC}");
_samplePane.Height = PaneHeight;
}
}
The use of SendKeys.Send comes from this msdn forum post. A Microsoft Moderator indicates that SendKeys.Send stops the re-sizing operation. The Height comparison in the if-statement ensures that we only prevent vertical height changes; if a user wants to horizontally expand or shrink Excel, we shouldn't prevent that.
You can specify the Docking of your task pane and lock it so that its position cannot be modified by the user this way:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
var taskPaneContainer = new TaskPaneContainer();
var taskPane = this.CustomTaskPanes.Add(taskPaneContainer, "My Task Pane");
taskPane.DockPosition = MsoCTPDockPosition.msoCTPDockPositionRight;
taskPane.DockPositionRestrict = MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
taskPane.Visible = true;
}
On the other hand, as far as I know, it is not possible to directly prevent a user from making the TaskPane invisible. Your best bet is probably to add a button in the Ribbon to make the TaskPane visible again.
I have two forms.
The first form is the mainForm, this never goes anywhere.
On opening the second form (saveForm), it will display over the top.
When i close this form, I want a certain piece of code in the mainForm to run.
I assume this is the correct way to get this to happen?
The code on saveForm when I close and return to the mainForm:
private void btnSaveDetails_Click(object sender, EventArgs e)
{
Delivery d = new Delivery(txtNameBox.Text, txtAddressBox.Text, txtDayBox.Text, txtTimeBox.Text, txtMealBox.Text, txtInstructionsBox.Text, txtStatusBox.Text);
mainForm.myDeliveries.Add(d);
this.Close();
}
Any ideas?
You can use the DialogResult returned to effect some change in your application. For example, if you provided the user with a dialog asking whether or not they want to delete all files and they respond by clicking the Yes button on your dialog, you would then delete the files.
More information about how to use DialogResult and ShowDialog vcan be found here: DialogResult
UPDATE: If the code you posted is from your "child" form, then what you've done so far is probably fine, BUT, you still need to provide a DialogResult on that form to communicate to mainForm that something was done. For example, you could do the following before this.Close():
this.DialogResult = DialogResult.OK;
Then, in the code after the call to childForm.ShowDialog(), check the DialogResult. If it's equal to DialogResult.OK, then you can perform whatever task you need to that indicates the user clicked OK.
(And, on a side note, Dispose() is not called when you use ShowDialog(); you'll need to clean things up yourself, if necessary.)
You have to set the DialogResult property of you dialog form. Either explicitly in code or by assingning the dialog result to a button on your form.
private void btnSaveDetails_Click(object sender, EventArgs e)
{
Delivery d = new Delivery(
txtNameBox.Text, txtAddressBox.Text, txtDayBox.Text,
txtTimeBox.Text, txtMealBox.Text, txtInstructionsBox.Text,
txtStatusBox.Text
);
mainForm.myDeliveries.Add(d);
this.DialogResult = DialogResults.OK;
}
No need to call Close() setting this.DialogResult does that for you if you called the dialog using ShowDialog().
On calling the form you have to do the following:
var frm = new MyForm();
if (frm.ShowDialog() == DialogResults.OK) {
// do what you want to do on success.
}