I want create using C# window with setted parent to my defined handle,
this is a other process window handle.
Anyone know how to do this?
Greetings,
If I understood your question correctly you should be able to achieve what you want by using something like this:
class Win32Window : IWin32Window
{
IntPtr handle;
public Win32Window(IntPtr handle) { this.handle = handle; }
public IntPtr Handle
{
get { return this.handle; }
}
}
static void Main()
{
IntPtr targetParent = // Get handle to the parent window
new MainForm().ShowDialog(new Win32Window(targetParent));
}
This will turn MainForm a child window of the specified window making it always appear above it. I use ShowDialog in the example, but this should also work for Show. This is specific for Windows Forms.
In WPF you can try the following:
var helper = new WindowInteropHelper(/* your Window instance */);
helper.Owner = // Set with handle for the parent
I quickly tried this after showing the WPF window and it seemed to work as expected, but WPF knowledge is not that great.
I believe the Handle will be read-only; therefore, the .Parent property is read-only. However, the .Owner property has a getter and a setter (ref. MSDN) ... however, you must have a reference to the Parent window.
Without more information, I will not be able to provide much more than that.
If your parent candidate is an unmanaged Window, check this link.
Related
I have 2 windows on my project. For example, on first window, I have a label. I want to change the text of this label from other window.
selectwindow win2 = new selectwindow();
win2.Show();
with this command we can open another window. but how can we change a property of an object from another window?
Your classes that inherit from Window can have their own properties and functions. Simply create a public function on your second Window class
public class SecondWindow:Window{
public void UpdateSomething(string text) {
//your code here
}
}
You can then call it in the first window with
var mywindow = new SecondWindow()
mywindow.Show()
mywindow.UpdateSomething("your text")
But you should read more on C# to begin with because this is quite basic and you shouldn't call functions in such a way because it produces spaghetti code. You should read more about WPF and MVVM
I would like to open the help dialog. I'm using this call:
public static void ShowHelp(Control parent, string url);
I'm launching it through a class that doesn't have access to the main control. So I'm passing null as the parent. It does seems to work but I want to make sure I'm not missing anything.
what does this "parent" argument stands for? what does .net do with it?
Is it safe to pass null as this argument?
I did notice in .Net source code this switch:
if (parent != null) {
handle = new HandleRef(parent, parent.Handle);
}
else {
handle = new HandleRef(null, UnsafeNativeMethods.GetActiveWindow());
}
Does it safe that it's using the "UnsafeNativeMethods" ?
The Parent control determines which window will own the dialog. If the parent is not a window, the ultimate parent (which should be a window) of this control will be used. If the parent parameter is null, the main window of the process will be chosen (if there is one).
This is needed so that the dialog can be modal and interaction with the parent window is blocked until the dialog has been dismissed.
I plan to use this method to display a notify icon so it can be accessed between the main form and child forms (found from another SO post)
public partial class MainForm : Form {
public MainForm() {
InitializeComponent();
notifier = this.notifyIcon1;
this.FormClosed += delegate { notifier = null; };
}
public static NotifyIcon Notifier { get { return notifier; } }
private static NotifyIcon notifier;
}
Is it necessary to add the FormClosed delegate? I would think that when the form everything else gets destroyed and freed up?
Edit: For clarification - I can confirm that using the code without the delegate above, when i close the form the system tray icon does disappear, also I did use the VS UI to drag/drop a NotifyIcon from toolbox so designer is handling initialization for me and I am using the constructor like above to access it.
If the notify icon is logically tied to this instance of the form then you shouldn't have it be a static field. Marking it as static is done to specifically say that it's not tied to one instance, but rather is shared between all instances.
I would think that when the form everything else gets destroyed and freed up?
If it were instance data it would be, but because it's static, and therefore not tied to the instance, it will not be cleaned up when the form goes away.
Of course, if this is the main form (and not a misnomer) then the entire application will end when the form closes, which will clean up everything regardless, static or not.
You need to set
nutifier.Visible = false;
notifier = null;
on closing. If not, the icon stays after the application was closed
I want to access my controls like button or textbox in mainWindow in WPF, but I can't do this.
In Windows Form application it's so easy, you can set modifier of that control to True and you can reach that control from an instance of that mainWindow, but in WPF I can't declare a public control. How can I do this?
To access controls in another WPF forms, you have to declare that control as public. The default declaration for controls in WPF is public, but you can specify it with this code:
<TextBox x:Name="textBox1" x:FieldModifier="public" />
And after that you can search in all active windows in the application to find windows that have control like this:
foreach (Window window in Application.Current.Windows)
{
if (window.GetType() == typeof(Window1))
{
(window as Window1).textBox1.Text = "I changed it from another window";
}
}
Unfortunately, the basics of WPF are data bindings. Doing it any other way is 'going against the grain', is bad practice, and is generally orders of magnitude more complex to code and to understand.
To your issue at hand, if you have data to share between views (and even if it's only one view), create a view model class which contains properties to represent the data, and bind to the properties from your view(s).
In your code, only manage your view model class, and don't touch the actual view with its visual controls and visual composition.
I found that in WPF, you have to cast Window as a MainWindow.
Looks complicated but it's very easy! However, maybe not best practices.
Supposing we have a Label1, a Button1 in the MainWindow, and you have a class that deals with anything related to the User Interface called UI.
We can have the following:
MainWindow Class:
namespace WpfApplication1
{
public partial class MainWindow : Window
{
UI ui = null;
//Here, "null" prevents an automatic instantiation of the class,
//which may raise a Stack Overflow Exception or not.
//If you're creating controls such as TextBoxes, Labels, Buttons...
public MainWindow()
{
InitializeComponent(); //This starts all controls created with the XAML Designer.
ui = new UI(); //Now we can safely create an instantiation of our UI class.
ui.Start();
}
}
}
UI Class:
namespace WpfApplication1
{
public class UI
{
MainWindow Form = Application.Current.Windows[0] as MainWindow;
//Bear in mind the array! Ensure it's the correct Window you're trying to catch.
public void Start()
{
Form.Label1.Content = "Yay! You made it!";
Form.Top = 0;
Form.Button1.Width = 50;
//Et voilá! You have now access to the MainWindow and all it's controls
//from a separate class/file!
CreateLabel(text, count); //Creating a control to be added to "Form".
}
private void CreateLabel(string Text, int Count)
{
Label aLabel = new Label();
aLabel.Name = Text.Replace(" ", "") + "Label";
aLabel.Content = Text + ": ";
aLabel.HorizontalAlignment = HorizontalAlignment.Right;
aLabel.VerticalAlignment = VerticalAlignment.Center;
aLabel.Margin = new Thickness(0);
aLabel.FontFamily = Form.DIN;
aLabel.FontSize = 29.333;
Grid.SetRow(aLabel, Count);
Grid.SetColumn(aLabel, 0);
Form.MainGrid.Children.Add(aLabel); //Haha! We're adding it to a Grid in "Form"!
}
}
}
var targetWindow = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is principal) as principal;
targetWindow .BssAcesso.Background = Brushes.Transparent;
just call any control of it from your current window:
targetWindow.ABUTTON.Background = Brushes.Transparent;
How can I access one window's control (richtextbox) from another window in wpf?
I was also struggling with this when I started WPF. However, I found a nice way around it similar to the good old fashioned win forms approach (coding VB.NET, sorry). Adding on what was said earlier:
To directly change properties of objects from a module or a different class for an active window:
Public Class Whatever
Public Sub ChangeObjProperties()
' Here the window is indexed in case of multiple instances of the same
' window could possibly be open at any given time.. otherwise just use 0
Dim w As MainWindow = Application.Current.Windows(0)
w.Button1.Content = "Anything"
End Sub
End Class
You obviously have to instantiate Whatever before ChangeObjProperties() can be called in your code.
Also there is no need to worry about naming in XAML regarding object accessibility.
Just declare your control like this to make it public:
<TextBox x:Name="textBox1" x:FieldModifier="public" />
You can then access it from another control.
The default declaration of controls is non public, internal and not public!
Access of the controls from within the same assembly is hence allowed. If you want to access a control on a wpf form from another assembly you have to use the modifier attribute x:FieldModifier="public" or use the method proposed by Jean.
This may be a slightly different answer, but let's think about why we need to pass data between forms.
obviously, the reason is 'visualization'.
use Delegate or Event.
There is no need to declare an element as Public just to make it visible.
only need to be able to transform elements within a window using a delegate , on a limited basis.
To access any control in another window is so simple. Lets say to access from a Login window to MainWindow. Here is the steps:
MainWindow MW = new MainWindow(); //declare the mainwindow
MW.Label1.Content = "Hello world"; //specify what control
MW.ShowDialog(); //check what happen to that control
Good programming
I've WinForms program with 2 GUI's. I work with one GUI and open another GUI using
var gui = new FormGui("SomeVar", someOthervar);
gui.ShowDialog();
I use ShowDialog() or Show() depending on what I need to get. When I'm done I would like to pass results (sometimes it's 2 strings, sometimes it's more then that) back to the Mother GUI which called Child GUI.
What's the best way to do that? I was thinking about using global variables but not sure if that's best approach?
You can create properties on your FormGui and set those within the form. When you're done with the form, you can grab those properties from your reference to the form:
var gui = new FormGui("SomeVar", someOthervar);
gui.ShowDialog();
var result = gui.Result;
EDIT: Regarding your comment:
Say your child form has some button on it or something that the user can interact with. Or if there's a close button they click on:
private void buttonCloseClick(object sender, EventArgs e)
{
this.Result = new ResultObject()....
}
EDIT #2 Regarding your second comment:
Yes, on your FormGui class, you need to define an object called Result:
public partial class FormGui : Form
{
public ResultObject Result {get;set;}
}
ResultObject is just something I'm making up. The point being that you're in control of FormGui, so you can add any property you want, and then access it on the FormGui object.
You can add a property on the FormGui class that contains the results you want to use in the parent form.
Also, you can use the result of ShowDialog() to pass information back as well - although this is limited values of the DialogResult enum.
You can call with ShowDialog, on the child window, use a new public property to set the result, and when you close the dialog the parent GUI should be able to see the result in the next code line.
The answer by BFree is enough for your task
I am suggesting easy way to add properties to all forms
Make a new class extend it with System.Windows.Form
public class Form : System.Windows.Forms.Form
{
//add properties
}
Check your properties in your forms