I have a mainwindown and I want to open a window inside that stays on top of it. But it seems like the window I want inside is opened before the mainwindow opens.
To solve this I need to open the window after initializecomponent of the mainwindow?
public partial class MainWindow : Window
{
public MainWindow ()
{
InitializeComponent();
OpenProjectsView();
}
private void OpenProjectsView()
{
ProjectsView projectWindow= new ProjectsView();
projectWindow.Owner = this;
projectWindow.ShowDialog();
}
}
Call OpenProjectsView( ) in Form.Activated event.
private void MainWindow_Activated(object sender, System.EventArgs e)
{
OpenProjectsView();
}
try this code
projectWindow.IsMdiContainer = True;
projectWindow.MdiParent = this;
projectWindow.Show();
Try this. It will launch your window after your main window is rendered.
public MainWindow()
{
InitializeComponent();
this.ContentRendered+= Window_ContentRendered;
}
private void Window_ContentRendered(object sender, RoutedEventArgs e)
{
OpenProjectsView();
}
public partial class MainWindow : Window
{
public MainWindow ()
{
InitializeComponent();
OpenProjectsView();
}
private void OpenProjectsView()
{
ProjectsView projectWindow= new ProjectsView();
projectWindow.Owner = this;
projectWindow.TopMost = true;
projectWindow.Show();
}
}
This will make the second window sit on top of the first, but because you create and show it during your parent window constructor, it will always appear (get instantiated) before your parent window.
This method allows that to happen, whilst you can still interact with both windows (Show() rather than ShowDialog()).
As others have mentioned, you can instantiate your window in an event, rather than the constructor, but that depends on exactly what you need ... your question is a little ambiguous! :O)
Related
I have a main window and it has a button. When I press the main window button, it will open sub-window. In sub window, I have a text box and when I enter the text and click the add button in sub-window, the text should display on the main window. How do I achieve this? Thanks in advance.
You can create parameterized constructor of MainWindow class and pass value of Textbox from subwindow to main window and in MainWindow you can set content to that label.
Here is the implementation
MainWindow.xmal.cs
public partial class MainWindow : Window
{
public MainWindow ()
{
InitializeComponent();
}
public MainWindow (string text) : this()
{
label.Content = text;
}
private void button_Click (object sender, RoutedEventArgs e)
{
Window1 win1 = new Window1();
win1.Show();
this.Close();
}
}
Here is the code for subWindow i.e. Window1.xaml.cs
public partial class Window1 : Window
{
private string text;
public Window1 ()
{
InitializeComponent();
}
private void button_Click (object sender, RoutedEventArgs e)
{
text = textBox.Text;
MainWindow mainWindow = new MainWindow(text);
mainWindow.Show();
this.Close();
}
}
You can simply modify the constructor of the second window :
public partial class Window1 : Window
{
string text;
public Window1 (string _text)
{
InitializeComponent();
this.text = _text;
}
}
I would add an event to your 'dialog' subwindow which the MainWindow can subscribe to as it instantiates it.
DialogWindow: (subwindow):
public class DialogInputEventArgs : EventArgs
{
public string Input { get; set; }
}
public partial class DialogWindow : Window
{
public event EventHandler<DialogInputEventArgs> InputChanged = delegate { };
private void SubmitInputButton_Click(object sender, RoutedEventArgs e)
{
InputChanged(this, new DialogInputEventArgs() { Input = this._inputTextBox.Text });
}
}
MainWindow:
private void ShowDialogButton_Click(object sender, RoutedEventArgs e)
{
DialogWindow dw = new DialogWindow();
dw.InputChanged += OnDialogInputChanged;
dw.Show();
}
private void OnDialogInputChanged(object sender, DialogInputEventArgs e)
{
// update the MainWindow somehow using e.Input (the text submitted in dialog)
}
If you need this mechanism for multiple windows I would go with something more generic, like a messagebus or observerpattern thing.
I'd suggest you to use CaliburnMicro framwework to achieve easier and better communication between your controls (assuming you are using MVVM pattern). You don't have to implement all features of CaliburnMicro, just EventAggregator to manage sending and handling messages between your controls.
Is there another way to access MainWindow's public variables than :
MainWindow mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
mainWindow.variable....
this work fine, but I'm creating a WPF application and integrating a USB Webcam to my project and using this code above to access MainWindow's variables. This causes some problems like program is still running when I close MainWindow and camera won't stop.
Any suggestions?
This is an over simplified example for what i wrote in comments(you really should look at mvvm the example below is not mvvm).
public class SelectedIndexData
{
public int SelectedIndex { get; set; }
}
public partial class MainWindow : Window
{
private readonly SelectedIndexData _selectedIndexData = new SelectedIndexData();
public MainWindow()
{
InitializeComponent();
}
private void ComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
_selectedIndexData.SelectedIndex = ComboBox.SelectedIndex;
}
private void ShowChildWindow(object sender, RoutedEventArgs e)
{
new ChildWindow(_selectedIndexData).Show();
}
}
public partial class ChildWindow : Window
{
private SelectedIndexData _selectedIndexData;
public ChildWindow(SelectedIndexData selectedIndexData)
{
InitializeComponent();
_selectedIndexData = selectedIndexData; // do whatever you want with your data here
}
}
This approach work also if you are developing a dll (you can't tell the same about Application.Current.MainWindow, which is clearer then your attempt anyways)
DependencyObject ucParent = this.Parent;
while (!(ucParent is MainWindow))
{
ucParent = LogicalTreeHelper.GetParent(ucParent);
}
mainview = ucParent as MainWindow;
You can pack this inside a method, save the variables that you need and you shouldn't have problems
To make sure you application shuts down when MainWindow is closed:
public MainWindow()
{
InitializeComponent();
this.Closing += (sender, args) => Application.Current.Shutdown();
}
I have two windows: window1 and window2. When I click a button in window1, window2 gets displayed.
How can I get focus/control onto window1 without closing window2? I am working on c#.net wpf using VS 13
In Window1:
private void go_Click(object sender, RoutedEventArgs e)
{
Window2 r = new Window2(s1);
r.ShowDialog();
}
In Window2:
public partial class Window2 : Window
{
static string data;
public Window2(String a)
{
data=a;
InitializeComponent();
TextBox.Text = data;
}
}
You can pass a reference of window1 to window2 when you construct it.
Then from your window2, you can invoke the Activate method on window1 to bring it to foreground again:
window1.Activate();
See MSDN documentation of this method.
EDIT: Since you're using ShowDialog instead of Show (you didn't mention this information at first in your question), things are a bit different: ShowDialog is supposed to display the window as a modal dialog, and thus you cannot give the focus back to window1 once window2 is open, you have to close window2 first.
I'm not sure what behavior you'd like to achieve, but you should try to use Show instead of ShowDialog, and then use the Activate method as described above.
Change this
private void go_Click(object sender, RoutedEventArgs e)
{
Window2 r = new Window2(s1);
r.ShowDialog();
}
change the constructor of Window2 add reference of window1
Something like this
public partial class Window2 : Window
{
static string data;
static Window window1;
public Window2(String a,Window parent)
{
data=a;
InitializeComponent();
TextBox.Text = data;
window1 = parent;
}
}
and change that method to this
private void go_Click(object sender, RoutedEventArgs e)
{
Window2 r = new Window2(s1, this);
r.Show();
}
Now from Window2 call this
window1.Activate();
from any method
I have the following classes:
MainWindow:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MainMenu mainMenu = new MainMenu(this);
menuFrame.Navigate(mainMenu);
UserPage userP = new UserPage();
contentFrame.Navigate(userP);
}
public void LoadAPage(Page page)
{
contentFrame.Navigate(page);
}
}
MainMenu:
public partial class MainMenu : Window
{
private Window switchPage;
public MainMenu(MainWindow mainP)
{
Window mainWindow = mainP;
InitializeComponent();
switchPage = mainP;
}
private void btn_navigate_user(object sender, EventArgs e)
{
UserPage userP = new UserPage(ServiceLogic);
//switchPage = Window.GetWindow(PageSwitcher);
//switchPage.LoadAPage(new UserPage());
}
As you can see, I'm trying to use the LoadAPage-method from the MainWindow. The MainMenu and UserPage are childs from the MainWindow. The problem is, no matter what I try, I cannot reach the LoadAPage method. I've tried setting the Owner but that doesn't work. When trying mainMenu.Owner = this;, Visual Studio says Mainmenu does not contain a definition for 'Owner``. When I give the parent class as a parameter to the child class, there are no errors but the methodLoadAPage` is unknown there.
What am I doing wrong? How should I solve this?
EDIT: Changing MainMenu to a Window instead of UserControl makes me able to set the Owner. Still, I can't reach the method.
What a mess :) Try this
private MainWindow switchPage;
public MainMenu(MainWindow mainP)
{
InitializeComponent();
switchPage = mainP;
}
private void btn_navigate_user(object sender, EventArgs e)
{
UserPage userP = new UserPage(ServiceLogic);
switchPage.LoadAPage(userP);
}
However i think you ll be better off using events, instead of passing your window object to its childs.
There is a child textbox control in an chlid window form created by main window form using thread technology, and I wanna implement this function: In the child window form, when I click a button (or Enter-key-down), it pass the text to the main window form. What can I do about that?
You need a way for the ChildWindow to send a message back to MainWindow. Following example should be useful:
Code:
An Interface to allow "communication" between windows
public interface IListner
{
void Send(String message);
}
MainWindow
public partial class MainWindow : Window, IListner
{
public MainWindow()
{
InitializeComponent();
}
public void Send(string message)
{
// Read the message here.
// If this code is called from different thread, use "Dispatcher.Invoke()"
}
public void OpenAnotherWindow()
{
// Since "MainWindow" implements "IListner", it can pass it's own instance to "ChildWindow"
ChildWindow childWindow = new ChildWindow(this);
}
}
ChildWindow:
public partial class ChildWindow : Window
{
private IListner Listner { get; set; }
public ChildWindow(IListner listner)
{
InitializeComponent();
Listner = listner;
}
private void OnTextBoxTextChanged()
{
// This will call "Send" on "MainWindow"
Listner.Send(TextBox1.Text);
}
}
A quick google will bring you back loads of results...
The best thing to do is probably when you create Form2 (the child) have a public method available where you can pass in an instance of Form1 (the parent) and then the same again on Form1 but pass a string rather than a instance of a form. So you would end up with something like this:
Form1 (parent):
private void Button1_Click_ShowChildForm(args..)
{
Form2 frm2 = new Form2();
frm2.Show();
frm2.GetInstance(this);
}
public void PassBack(string var)
{
TextBox1.Text = var;
}
Form2 (child):
private static Form1 _frm1;
public void GetInstance(Form1 Frm1)
{
this._frm1 = Frm1;
}
private void Button2_Click_Close(args...)
{
_frm1.PassBack(this.TextBox2.Text);
this.Close();
}
Something like that ^^^ should do the trick. ;)
NB. You could probably tidy it up a bit and if you really wanted to you could probably override the Show method of the Form2 to accept an instance of Form1 instead of declaring a separate method but you get the idea.