I have a C# application in which a function is performed which requires a date. The original specification said that the current date could always be used, but now I have to allow for the user to be able to change the date on demand.
The problem is, this operation executes completely in the background. There is only a menu item which the user clicks to start the process. So I wanted to add, when the user clicks the menu item, a modal window which asks the user for the date to be used, and returns the date entered. I have not been able to find a way to do this.
Do I need to create a form which has only one item on it - a DatePicker - and design it to look like a modal window? Or is there an existing modal window class which does exactly this?
I don't think there is a modal window built into the framework.
You will have to create a new windows form. Put a datepicker on it. Make its modifier public and do something like this:
private void MenuItemClick(objec sender, EventArgs e)
{
var userEnteredDate = DateTime.MinValue;
FormWithDate fmNewFormWithDateOnIt = new FormWithDate();
fmNewFormWithDateOnIt.ShowDialog();
userEnteredDate = fmNewFormWithDateOnIt.dtTimePickerOnForm.Value;
fmNewFormWithDateOnIt.Dispose()
//Do your thing
}
UPDATE: You could put a button on the form and set its DialogResult = OK and then do the following:
if (fmNewFormWithDateOnIt.ShowDialog() == DialogResult.OK) //Not clicked the red close button on the form
{
userEnteredDate = fmNewFormWithDateOnIt.dtTimePickerOnForm.Value;
}
Related
I have a winform application where I've written my own little color picker that will only display system colours. It's basically a TableLayoutPanel with a bunch of smaller panels added to it, to which I just set the background color.
Pretty simple:
Now I'm opening this form for with:
using (frmColourWindow colourPicker = new frmColourWindow (Cursor.Position.X, Cursor.Position.Y, findingPriority))
{
colourPicker.ShowDialog();
if (!colourPicker.SelectedColor.IsEmpty)
{
pnlColor.BackColor = colourPicker._SelectedColor;
}
}
and closing it with by setting the DialogResult when the user has clicked on one of the color panels.
This all works pretty good, the only thing I can not manage to get right is by closing the form when it loses focus (E.g. when the user clicks somewhere else or starts typing). I've had a look at the Deactivate, LostFocus, and Leave events. Just can't seem to get those events to fire when I want them to. Maybe I'm missing something obvious?
As I mentioned in the comments, when using the ShowDialog() you can only use the Dialog you have opened and thus it never looses focus, so event like Deactivate, LostFocus and Leave won't work.
You need to use the Show() command to use those event to close the opened Form.
As to addressing the issue you pointed out in the comments about assigning the color to the object. you can do the following:
Declare a public Property
Color SelectedColor {get; private set; }
In your color picker and change your using statement to this:
var colourPicker = new frmColourWindow (Cursor.Position.X, Cursor.Position.Y, findingPriority);
colourPicker.Closed += (o, args) => { pnlColor.BackColor = colourPicker.SelectedColor };
colourPicker.Show();
This is of course just one of many possible solutions for that.
You can achieve this by displaying the form with the Show() method and then using the Form.Deactivate event.
i have 2 project in 1 solution and each project have 1 form. In form 1 i have label and button, and i want when i click on button it will show in form 2 labeltext in form 1.
my code in form 1:
WindowsFormsApplication1.Form1 layarForm1 = new WindowsFormsApplication1.Form1();
layarForm1.Show();
layarForm1.LabelText = no_antrian.Text;
//layarForm1.LabelText = this.Refresh();
form2(in other project but in same solutions, and i have reference to form 1):
public string LabelText
{
get
{
return this.ruang_1.Text;
}
set
{
this.ruang_1.Text = value;
}
}
my code work for first time but when i click button again it will show new form. is there any ways that label text in form 2 will refresh after button click. And i dont want to use dispose form because in form 2 i have video played that will start again if i use dispose() and show()
Two projects = 2 executable you need to use shared memory or named pipes to send the data across from one exe to another, or use winapi such as SendMessage once you get the window handle of the other window and the find the child window handle via EnumChildWindows.
Why not use the two forms in the same project?
The problem is every time the button is clicked, an instance of the form is created. You need to check whether the form is already open and if not create an instance, show the form and update the label.
If the form is already open, all you need to do is to update the label and set focus on the form.
You can use Application.OpenForms to iterate through all one forms and check whether the form is in that collection.
Something like
foreach (Form frm in WindowsFormsApplication1.OpenForms)
{
if (frm.Name == "MY_FORM_NAME") then
frm.LabelText = no_antrian.Text;
else
{
WindowsFormsApplication1.Form1 layarForm1 = new
WindowsFormsApplication1.Form1();
layarForm1.Show();
layarForm1.LabelText = no_antrian.Text;
}
}
I am using visual studio 2010 in C#. Basically, I have my first form with my main code, then I have a second form set up where the user is prompted to enter multiple paths. However, only on form1 do any folderBrowserDialogs open. On form2, regardless of what I try so far, the button simply clicks and nothing changes. I have not altered anything but variables really from the one I use on form1 and it works just fine.
Here's a bulk of my code, it contains one of the folderBrowserDialog's that will not work. This is all form form2:
string mexPath;
string ausPath;
string canPath;
string chilPath;
public CultureInfo targetCulture1 = new CultureInfo("es-CL"); //Chili
public CultureInfo targetCulture2 = new CultureInfo("de-AT"); //Austria
public CultureInfo targetCulture3 = new CultureInfo("es-MX"); //Mexico
public CultureInfo targetCulture4 = new CultureInfo("fr-CA"); //Canada
PassoloU.PassoloApp app = new PassoloU.PassoloApp();
//Respective Language Paths
private void spanPath_Click(object sender, EventArgs e)
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
mexPath = folderBrowserDialog1.SelectedPath;
}
}
I have established 4 different folderBrowserDialog's in the design and I am not sure where to go from here.
EDIT: Thank you for the help. For some reason, adding "_1" to the end of each click events name allowed the dialog boxes to open. So now each reads "spanPath_Click_1", "germPath_Click_1", etc. I have no idea why this is an issue though, but it seemed to have solved my problem.
Open your Form2 in Designer mode, select the button, go to properties and ensure the click event is attached to the button as MichaC mentioned.
I just tried to put together an example with two forms, Form1 with a label, FolderBrowserDialog, and a button. Form1 displays the browser dialog, and then the selected folder path is displayed in the label. If you click a button it displays Form2 with similar controls. Both the FolderBrowserDialogs worked just fine. Let me know if you need me to post it.
Basically I have three empty slots.
These three slots represent three chosen items of a game.
When I click one of the empty boxes, I want to display this pop up box with a collection of all of the items and some checkboxes where users can choose certain filters and the items filter out.
The construction of such "window" is not hard for me, what I am having trouble figuring out is how the window should exist in relation to the main Window.
Should I place this new pop up in a new Window and have it appear when a user clicks, then on clicking the item, send that chosen item back to the main Window event?
How would you do it? I'm kind of new to WPF and would appreciate some feedback.
Rather than a popup window you can have a flow design.
Screen 1
The user clicks on one of the slots to view more information or add filter options for that slot. Clicking on the slot opens Screen2.
Screen 2
In this screen the user can filter the items he wants. The active slot (slot being edited) is highlighted on the left. More information on the chosen item can also be shown. At the bottom at the apply and cancel (back) buttons. A prompt can be shown in case the user cancels without saving/applying.
You can apply WPF Styles and Animations to make your application more visually appealing.
What you can do is open your other window as a new form and use the method ShowDialog() instead of Show(). This way, you're gonna be able to use the DialogResult of your window to know if the user cancelled or selected an item and you can make a method in this window to get the value you need.
frmList frmPopup = new frmList();
DialogResult response = frmPopup.ShowDialog(); //Execution of this method stops until you close frmPopup
if(response == DialogResult.Ok) //Make sure you set the DialogResult value in your form when you are closing correctly
{
frmPopup.getValue(); //Method of the window that would return the value you're looking for
}
Assuming that since you have tagged this question with "popup" you want a dialog box you could create event handlers for the click event on the boxes something like the following:
private void On_BoxClicked(sender object, EventArgs e)
{
PopUpBox dialog = new PopUpBox();
var result = PopUpBox.ShowDialog();
if (result == true)
{
//process the result here accessing the properties that
//are needed through the dialog object.
}
}
You will need to set the DialogResult for the form to be true. I ussually just add to the OnClick event for the button that you wish to return as being successful for, and close, the following:
this.DialogResult = true;
For more information about custom dialog forms see: Custom Dialog Boxes
Using RoutedCommands
A more sophisticated approach would be to add a command to the form with the parameter for each box. Code for the actual handling off adding the items would be more or less the same, but it does add certain features (such as disabling the click event unless certain conditions -- defined in the CanExecute method -- are met):
//the custom command
public static RoutedCommand AddToBox = new RoutedCommand();
//add the can execute method
private void AddToBox_CanExecute(sender object, CanExecuteRoutedEventArgs e)
{
//assuming that this can always execute
e.CanExecute = true;
}
//Executing the command when the button is clicked
//Show the dialog box and get the response
private void AddToBox_Executed(sender object, ExecutedRoutedEventArgs e)
{
PopUpBox dialog = new PopUpBox();
var result = dialog.ShowDialog();
if (result == true)
{
string box = e.Parameter;
//get the result of the dialog where GetResult() is the
//method that returns the necessary information.
//here set to object for the sake of example
object[] obj = dialog.GetResult()
switch (box)
{
case "box1":
//put value into box 1
case "box2":
//put value into box 2
case "box3":
//put value into box 3
}
}
}
In order to use the command add a reference to the command. First you will need to add a reference to the namespace, presesuming that this command is contained in Example.Window1:
<Window ...
xmlns:cmd="clr:NameSpace:Example" ... />
Then add the Command Binding
<Window.CommandBindings>
<CommandBinding Command="{x:Static cmd:Window1.AddToBox}"
CanExecute="AddToBox_CanExecute" Executed="AddToBox_Executed" />
</Window.CommandBindings>
Finally, add the command and parameter to the XAML, for example:
<Button Name="Box1"
Command="{x:Static cmd:Window1.AddToBox}"
CommandParameter="Box1" />
For more information about custom routed commands in WPF see: RoutedCommand Class
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.