I have a save as image feature for charts in my application. The chart control is a custom user control with custom logic in them. It also has some scaling based on size, zoom etc. However, while saving them as an image I would like to give the user the option to set the size of the image (eg: 800x600 px # 300 DPI).
To do this I have created a Form with textboxes/checkboxes etc for various settings for image. One of these TextBoxes is for the file name. The file name textbox is readonly and is accompanied with a browse button which shows a SaveFileDialog when clicked.
The user clicks "Save As Image" in the main form's menu. I show the ImageExportDialog using the code below:
using(ImageExportDialog dlg = new ImageExportDialog())
{
if(dlg.ShowDialog() == DialogResult.OK)
{
//get the settings selected by the user and generate the image
}
}
In the ImageExportDialog, the user clicks on the browse button and the SaveFileDialog is shown as follows:
using(SaveFileDialog dlg = new SaveFileDialog())
{
if(dlg.ShowDialog() == DialogResult.OK)
{
txtFileName.Text = dlg.FileName;
}
}
Now the problem is, when the user clicks on "Save" button in the SaveFileDialog, as expected the txtFileName.Text is set, but the parent custom dialog also seems to return from the ShowDialog method and the DialogResult is the same as the one for SaveFileDialog! The control then goes on to the "get the settings selected by the user and generate the image" part of the code above.
Not really sure what I am doing wrong here!
Arghhh!!!
Found out the issue myself. I had copy-pasted the OK button of the ImageExportDialog to create the Browse button for the SaveFileDialog.
Guess what, the Browse button had it's DialogResult property set to "OK"! Changing it to "None" solved the issue.
Related
Edit:
This is not a duplicate of Icons in TabControl C# - How?. The question there is about adding icons to tab pages. Here it is about how the change the error provider error icon position to be inside the header instead of to the right of the tab page itself. Also, the error provider error icon has the functionality that when you hover the mouse on it, you see the error text, which you do not see if you simply add an icon to the header.
I have a form with a TabControl. The form has also an ErrorProvider. When I try to use the following code:
errorProvider1.SetError(tabPage1, "error");
The error icon is shown to the right of the tab page, and it is cut-off by the tab control itself:
I would like the icon to be shown next to the tab page header. Something like this (made with Photoshop):
I do not know where to start, or how to approach this.
Edit:
I have a class responsible for adding errors to a control, and showing them using an error provider. This class is used for TextBoxes, NumericUpDowns etc. I would like to use it also for TabPages. The problem is that when I use it for tab pages I get the result shown above. The trick of adding an error icon to the header using an ImageList and then add a tooltip is not good, because it is specific to tab pages, and I cannot implement it in my class which is general to all controls. So I really need to change the settings of the tab page so when I use errorProvider.SetError(...) it is shown in the header.
ErrorProvider shows error icon of the TabPage in tab page's client area.
By playing with IconAlignment or IconPadding, you can show error icon of TabControl on one of the tab pages' headers, but it's error icon for the whole TabControl.
In a real application each of the tab pages can contain controls which are not valid and you may want to show the validation icon on tab pages not for the tab control.
My suggestion is using tab page icon by setting ImageList containing the error icon as image list of the TabControl and by setting ImageIndex of the TabPage, show or hide the image icon. This way you can show the error icon for every tab page which needs it:
Example
To setup the example, follow these steps:
Create a Form.
Drop a TabControl, an ErrorProvider and an ImageList on the Form.
Set ImageList property of tabControl1 to imageList1.
Drop two TextBox on tabPage1.
I assume, just for example, you are going to validate these two text box controls using Validating event. The key point is here. When you validate any control, check if it's hosted in a TabPage, check validity of all children of TabPage and set the error icon based on that:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.AutoValidate = AutoValidate.EnableAllowFocusChange;
imageList1.ColorDepth = ColorDepth.Depth32Bit;
imageList1.Images.Add(errorProvider1.Icon);
tabControl1.ImageList = imageList1;
textBox1.Validating += textBox_Validating;
textBox2.Validating += textBox_Validating;
}
private void textBox_Validating(object sender, CancelEventArgs e)
{
var textBox = (TextBox)sender;
if (string.IsNullOrEmpty(textBox.Text))
{
this.errorProvider1.SetError(textBox, "Value is required.");
e.Cancel = true;
}
else
this.errorProvider1.SetError(textBox, null);
var tabPage = textBox.Parent as TabPage;
if (tabPage != null)
ValidateTabPage(tabPage);
}
void ValidateTabPage(TabPage tabPage)
{
var tabIsValid = tabPage.Controls.Cast<Control>()
.All(x => string.IsNullOrEmpty(errorProvider1.GetError(x)));
if (tabIsValid)
tabPage.ImageIndex = -1;
else
tabPage.ImageIndex = 0;
}
You can do the following.
Rectangle rc = tabControl1.GetTabRect(0); // Replace with the index of Tab required
errorProvider1.SetIconPadding(tabControl1, -rc.Left-20);;
errorProvider1.SetError(tabControl1, "Error String");
You also need to set
errorProvider1.SetIconAlignment(tabControl1, ErrorIconAlignment.TopLeft);
Sample (With Second Tab Selected - based on comments),
You would need to prepend whitespace to your TabPage Text to ensure there is sufficient space for showing the icon
With Icon on Second Tab
I have created a ToolStripMenuItem called "About". Underneath "About", I have a submenu called "About MatchingGame". Upon clicking on "About MatchingGame", I want it to display a dialog box. In that box, I want to be able to show an image and some text (one field on top of another).
So far, I have this code for the about menu:
private void aboutMatchingGameToolStripMenuItem_Click(object sender, EventArgs e)
{
Form dlg1 = new Form();
dlg1.ShowDialog();
}
This gives me the form dialog that I need, though it is still blank. Is there a way to get the dialog box to show up when looking at the design so that I can add a picture box to it? When I click on "About MatchingGame" from the design file, it just lets me change the text and does not open the form dialog to let me put anything in it. How can I get the dialog form to display what I need (an image and a text field)? I have tried added open file dialog to the source code, but I could not get that to work (and it doesn't solve the problem of the text). Any ideas?
Yes, create a new Form and add it to your project. Give it a name like "MyForm". Then you can change the form in the designer.
Instead of doing Form dlg1 = new Form();, do MyForm dlg1 = new MyForm();. The rest of your code can be the same.
I have C# code linked to an xaml file that builds a GUI. In the GUI, when I click on an option, the photo appears, as I want. However, I can't figure out how to make it so the user has the option to close the photo. Here's my C# code:
public void help_click(object sender, RoutedEventArgs e)
{
Image img;
img = new Image();
Uri diagram = new Uri(#"pack://application:,,,/PTDGUI;component/Content/Icons/controlmap.png", UriKind.RelativeOrAbsolute);
img.Source = new BitmapImage(diagram);
canvasSpace.Children.Add(img);
}
Image is not based on Control. You may require to customize for this behavior by either writing custom control or trapping any other control events to close this image.
This discsussion(stackoverflow) explains both the options I've mentioned, should help in understand and implementing what you rquired.
you can use the same help button for both, initially button will display "Help", When user clicks help, load the image and change the button text to "Close" and toggle it back to "Help" when users clicks again.
if(button.Text ="Help")
{
---load image
button.Text = "Close";
}
else
{
--Clear image
button.Text ="Help"
}
you may also use bool flag instead of checking text.
I am trying to make a folder selection which would show an error if there isn't enough space on the selected drive. I have created a custom designed error and dialog form, but there is a problem with using the FolderBrowserDialog.
Here is my actual code:
frmDialog dialog = new frmDialog("Install software", "The software cannot be found. Please select the path of the executable or let the launcher install it for you.");
dialog.SetYesButtonText("Install software");
dialog.SetNoButtonText("Browse for executable...");
if (dialog.ShowDialog() == DialogResult.Yes)
{
fbd = new FolderBrowserDialog();
fbd.Description = "Please select where do you want to install the software!";
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK) // + space checking, but I deleted it for debugging now.
{
frmError error = new frmError("Not enough space", "Please select a folder with at lease 22 MB of free space.");
error.ShowDialog();
}
}
I will actually make a loop afterwards which will run until the user selects a folder with enough space or cancels the selection.
The problem is that the error dialog does not get any focus. So when the user selects the folder, the FolderBrowserDialog disappears, and the error dialog shows up in a new window, but the Visual Studio's window gets the focus instead of the error dialog. As I experienced, this issue is not existing with my own forms, so if I changed the fdb to frmDialog, all the three dialogs would appear with focus after each other.
Set the owner of the dialogs like this:
fbd.ShowDialog( dialog );
error.ShowDialog( dialog );
I recommend to set the owners of the other dialogs to set a parent child relationship. So when you close the parent form, the child forms closes to. And also put a using block around your forms if you're using the ShowDialog calls.
I have a query that. I have a splash form that is my first form of the project and I want to change the background image of that form after that is closed. For example my software starts and after splash form and in setting I have a function to change the background image of the splash form. Can I change the background image when the form is closed? (as my splash form is closed when user enters the setting form).
I have written this code form changing the background image but I don't know how to change the form image when the splash form opens it should open changing the image from the open file dialog.
My code is:
var FD = new System.Windows.Forms.OpenFileDialog();
FD.Filter = "jpeg files|*.jpg";
if (FD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string fileToOpen = FD.FileName;
System.IO.FileInfo File = new System.IO.FileInfo(FD.FileName);
BackgroundImage = Image.FromFile(FD.FileName);
}
Ok try the below
you already set a background image for your splash screen
eg : it location was c:\sam.jpeg
Now try the below code on form close event
System.IO.File.Delete(#"C:\Sam.jpeg");
Image.FromFile(FD.FileName).Save(#"C:\Sam.jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
now it delete the old file and set the new image on old name...
at the time of reload it shows the new background image...
You load the splash image from somewhere, so then just replace that image with the one selected by the user with the OpenFileDialog and then the new image will be loaded the next time the splash is shown.
EDIT: Further explanation
An example of a solution. Store the image in the same folder as the application (for example: "splash.png") and then you can load that on the Splash Form Load event for example. Now, when the user wants to replace the image from settings with the open file dialog, you simply have to copy the file selected to the application's folder (Application.StartupPath should get you the path to the app folder) and overwrite the old splash.png (maybe you can rename the old one before overwriting or something) and then the next time the application will load, that's the image the Splash form will load.
This is a simple solution that can be improved upon, but as a first attempt it should produce the result you want.