Is it possible to disable the hittest on a Windows Forms window, and if so, how do I do it? I want to have a opaque window that cannot be clicked.
Thanks in advance,
Christoph
If you're talking to a different process, you need to send and retrieve Windows messages.
http://www.c-sharpcorner.com/UploadFile/thmok/SendingWindowsMessageinCSharp11262005042819AM/SendingWindowsMessageinCSharp.aspx
Have a look at this link:
Using Window Messages to Implement Global System Hooks in C#
http://www.codeproject.com/KB/system/WilsonSystemGlobalHooks.aspx
Global system hooks allow an application to intercept Windows messages intended for other applications. This has always been difficult (impossible, according to MSDN) to implement in C#. This article attempts to implement global system hooks by creating a DLL wrapper in C++ that posts messages to the hooking application's message queue.
Do you want a window that cannot be moved? Set FormBorderStyle to none.
Well, I still don't know much about your use case, but I'll take a stab anyway, and provide a simple example.
I assume that you want to control something on the main form from your floating form.
To do this, you need a reference to your main form from your floating form. You do this by creating a constructor overload in your floating form that accepts an instance of your main form, like this:
public FloatingForm(MainForm mainForm)
{
InitializeComponent();
_mainForm = mainForm;
}
The floating form contains a textbox named floatingFormTextBox, and a button named Button1. The partial class for the floating form looks like this:
public partial class FloatingForm : Form
{
MainForm _mainForm;
public FloatingForm()
{
InitializeComponent();
}
public FloatingForm(MainForm mainForm)
{
InitializeComponent();
_mainForm = mainForm;
}
private void button1_Click(object sender, EventArgs e)
{
_mainForm.DoSomething(floatingFormTextBox.Text);
}
}
The main form just contains a textbox named mainFormTextBox. When the main form loads, it creates an instance of the floating form, passing a reference to itself to the floating form's new constructor overload. The partial class for the main form looks like this:
public partial class MainForm : Form
{
FloatingForm _floatingForm;
public MainForm()
{
InitializeComponent();
}
public void DoSomething(string text)
{
mainFormTextBox.Text = text;
this.Refresh();
}
private void MainForm_Load(object sender, EventArgs e)
{
_floatingForm = new FloatingForm(this);
_floatingForm.Show();
}
}
Now, when I put some text into the textbox of the floating form and click the button, the text shows up in the textbox of the main form.
Related
I tried opening a second form using a button on my main form, but when I close the second window, I can't open it again.
I added the following code to my main form:
settings_window secondForm = new settings_window();
private void settings_button_Click(object sender, EventArgs e)
{
secondForm.Show();
}
But when I try to open the second form named settings_window the second time, I get the following error: System.ObjectDisposedException.
I found the following code to fix this but I don't know where to place it:
private void settings_window_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
e.Cancel = true; // Do not close the form.
}
You can avoid storing references of Forms and use a simple generic method that shows a Form when an instance of it already exists or creates a new one (and shows it) when none has been created before:
private void ShowForm<T>() where T : Form, new()
{
T? f = Application.OpenForms.OfType<T>().SingleOrDefault();
if (f is null) {
f = new T();
f.FormClosing += F_FormClosing;
}
f.Show();
BeginInvoke(new Action(()=> f.WindowState = FormWindowState.Normal));
void F_FormClosing(object? sender, FormClosingEventArgs e)
{
e.Cancel = true;
(sender as Form)?.Hide();
}
}
When you need it, call as ShowForm<SomeFormClass>(), e.g.,
ShowForm<settings_window>()
Note:
This code uses a local method to subscribe to the FormClosing event.
You can use a standard method, in case this syntax is not available.
BeginInvoke() is used to defer the FormWindowState.Normal assignment. This is used only in the case you minimize a Form, then right-click on its icon in the TaskBar and select Close Windows from the Menu. Without deferring this assignment, the minimized Form wouldn't show up again.
When the starting Form closes, all other Forms close as well
This code supposes nullable is enabled (e.g., see object? sender). If nullable is disabled or you're targeting .NET Framework, remove it (e.g., change in object sender)
Is secondForm a private field of the main form class?
It should work then.
Alternative solution is to show it as as modal - ShowDialog()
Also if you want to save some data in your second form, just use some data initialization from constructor, then saving to first/parent form.
I think you need to create a new instance of the form each time you want to open it. It will create a new instance of the settings_window form each time the button is clicked.
private void settings_button_Click(object sender, EventArgs e)
{
// Create a new instance of the form
settings_window secondForm = new settings_window();
secondForm.Show();
}
Your code shows a class that you have named settings_window, which gives us a hint about what its intended use might be. In general, for a form that behaves "like" a settings window, that you can call multiple times using the same instance, you can declare a member variable using this pattern:
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
// Provide some means, like a menu or button, to show 'secondForm'
settingsMenu.Click += onClickSettingsMenu;
// Dispose the settings_form when the MainForm does.
Disposed += (sender, e) => secondForm.Dispose();
}
// By instantiating it here, its public default or persisted
// properties are immediately available, for example even
// while the main form constructs and loads the initial view.
settings_window secondForm = new settings_window();
private void onClickSettingsMenu(object? sender, EventArgs e)
{
if(DialogResult.OK.Equals(secondForm.ShowDialog()))
{
// Apply actions using the properties of secondForm
}
}
}
This is suitable for any form when you want to:
Repeatedly show and hide the form (e.g. a "Settings" form where the user can change the options multiple times).
Retrieve the default or the persisted properties of the form from the outset even if it's never been shown.
Use any of the form's public properties (e.g. GameLevel, SortType etc.) at any given moment while the app is running, even if the form isn't currently visible.
Display the form modally meaning that "no input (keyboard or mouse click) can occur except to objects on the modal form".
The reason it works is that calling ShowDialog (unlike calling Show) intentionally does not dispose the window handle, and this is to support of this very kind of scenario. The app is then responsible for disposing the resource when the app closes.
The Microsoft documentation for ShowDialog explains how this works.
Unlike non-modal forms, the Close method is not called by the .NET Framework when the user clicks the close form button of a dialog box or sets the value of the DialogResult property. Instead the form is hidden and can be shown again without creating a new instance of the dialog box. Because a form displayed as a dialog box is hidden instead of closed, you must call the Dispose method of the form when the form is no longer needed by your application.
So I have user control I want to hide/send to back and I want to call the public function in my form where the user control is, from the control itself.
I have a button in the user control with the following code:
mainboard MAIN = new mainboard(); // mainboard is a form to call to.
MAIN.PastLockScreen(); // PastLockScreen is a public void inside mainboard
When I click the button the public function in mainboard does not get called. There are no errors, what am I doing wrong, and how can I call a function in a form from a user control?
void inside mainboard
public void PastLockScreen()
{
lockscreen1.SendToBack(); // lockscreen1 is the usercontrol that this function gets called from
}
The void is being referenced but not called?
Edit: I have done some investigating and turns out that my timers I have in any form or control, also dont work. But buttons on the actual form itself do work. (and yes I did do timerName.Start(); when the form/control loads.)
Solved the issue above, my timers needed to display time, which the time string I defined inside the class instead of inside the timer.tick
From within the UserControl, just cast ParentForm to type mainboard:
// .. form within the UserControl that is CONTAINED by form mainboard ...
private void button1_Click(object sender, EventArgs e)
{
mainboard MAIN = this.ParentForm as mainboard;
if (MAIN != null)
{
MAIN.PastLockScreen();
}
}
Note that this is a TIGHTLY COUPLED approach that limits your use of the UserControl to only mainboard.
A better approach would be to make the UserControl raise some kind of custom EVENT that the mainboard form then subscribes to. When the event is received then the form itself would run the appropriate method. This would mean you could potentially utilize the UserControl in a different form without changing any code within it. This latter approach would be LOOSELY COUPLED.
Try This
In Form1
to Show the Form2
Form2 frm2 = new Form2();
frm2.Show();
To call the method do you want
Form2 cmd = new Form2();
cmd.PastLockScreen();
In Form2
public void PastLockScreen()
{
this.SendToBack();
}
I'm making a windows form app and I have one form that represents a base form and it gets data from a different class (that's almost like a database):
private void base_form_Load(object sender, EventArgs e)
{
database_class dc = new database_class();
button1.Text =dc.Name;
}
NOTE: The reason why this code is in the form_Load is because it doesn't show up, unless I put it there, which I find strange, but it might not be?
I have a main form, that acts like a menu - it has four buttons on it and all the buttons lead to the base form. The database class is actually supposed to change the names of the controls in the base form based on the what button is chosen in the main form(menu). The base form has a lot more buttons than the main form.
Since this is confusing, here's an example of what I want to do: If the menu had options (buttons) Mozart, Beethoven, Liszt, Chopin - when people click on Mozart they're supposed to get buttons with the names of his compositions, if they click Beethoven then they get his compositions and so on.(These buttons in the base form do lead to something else, if that's important/helpful). The reason I'm not making separate forms for these menu buttons, is because I have a lot of buttons and I don't think making plenty of forms is ideal (it's a simple app, I don't want to slow it down with a lot of forms).
My question is what is the best way to do this? Do I have to somehow assign the data I want to the button (mouse) click events in the menu (main form)? Is there a possibility of having different form loads in the base form, that can be assigned to the mouse clicks in the menu?
Thank you for your time.
Example constructor as requested - form has a richTextBox that gets populated by the constructor and also a string value that's used later:
public partial class Form2 : Form
{
public string _filename;
public Form2(string text, string filename)
{
InitializeComponent();
richTextBox1.Text = text;
_filename = filename;
}
}
Create an instance of this form from the main form:
private void button1_Click(object sender, EventArgs e)
{
string textForRTB = "Some text";
string valueForFilename = "\some\file\name";
Form2 frm2 = new Form2(textForRTB, valueForFilename);
frm2.Show();
}
I'm working on a c# program and I want a panel to appear on a form when a button is clicked in another. So when the add button is clicked on form2 the panel requesting the details for this to be possible will be displayed on form 1.
I currently have a static method set up in form1 which can be accessed from form2 - however due to panel.Show() being non static it won't allow me to use this in the function.
In Form1 I have:
public static void showPanel()
{
panel.Show()
}
In my second form I have the following:
private void btn_add_Click(object sender, EventArgs e)
{
form1.showPanel();
this.Hide();
}
I have tested with just having the static function show a message box which works. Is it possible to do it the way I want or do I need to take a few steps back and try a different technique?
Are we talking about a new instance of the second form if so you can try to instantiate the new form using:
Form newForm = new YourFormName(potential parameters);
newForm.showPanel();
newForm.Show();
If you want to execute the form on an open form you can give the first form a reference(field with instance) of the second form. Or you can try using: Application.OpenForms. if you give it [1] it'll give you the second open form probably. You can also use .OfType to get the correct form in case your form order isn't always the same.
how to control main form from another form example I want to access the table in main form from another form in wpf?
You can either use UI automation (which would only let you interact with it as if you were a user clicking on/typing in the controls):
http://msdn.microsoft.com/en-us/library/dd561932(VS.85).aspx
Or you can use code behind to pass a reference from one window to the other, probably in your Application class.
There is nothing specific to WPF that makes either option any easier or harder to implement.
salamonti,
Do you want to access a control on the main form or the data that the control is displaying? If the latter I would suggest you to keep the data in a separate area than the control presenting it. This can be achieved with MVVM and several other view separation patterns. You can also use Routed Events and Routed Commands to execute code in one "form" from a different one.
If you want to access the "main form" from a child form, you can create a property on the child form of type FrameworkElement for example. Then, when you create the child form, just populate this property with the instance of the main form. This way you'll have access to whatever you want in the main form.
this is a tiny sample of communication between windows in WPF
you can refer to controls as the way you do with class fields, cause that's what they are
public class Form1 : Window
{
public DateTime FormCreationDate {get; set;}
private void button1_Click(object sender, RoutedEventArgs e)
{
Form2 a = new Form2();
a.Owner = this;
a.Show();
}
}
public class Form2 : Window
{
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.label1.Content = string.Format(
"the owner of this window was created on {0}",
((Form1)this.Owner).FormCreationDate.ToString());
}
}