I have a WPF project with PRISM. In my bootstrapper I have following code.
protected override DependencyObject CreateShell()
{
Form1 form1= new Form1();
Form2 form2= new Form2();
var mainWindow = new MainWindow();
mainWindow.Show();
mainWindow.Activate();
RegionManager.SetRegionManager(form1, this.Container.Resolve<IRegionManager>());
RegionManager.SetRegionManager(form2, this.Container.Resolve<IRegionManager>());
RegionManager.UpdateRegions();
return mainWindow;
}
protected override IModuleCatalog GetModuleCatalog()
{
var moduleCatalog = new ModuleCatalog();
moduleCatalog.AddModule(typeof(MainModule));
moduleCatalog.AddModule(typeof(Form1Module), InitializationMode.OnDemand);
moduleCatalog.AddModule(typeof(Form2Module), InitializationMode.OnDemand);
return moduleCatalog;
}
On MainForm I have ListBox and button. When we select some item in the ListBox and click "Show" button the form1 is shown with some data and the mainWindow is hidden. Form1 also has button "Go to Main", when user clicks it I do form1.Hide() (hide form1 with data) and mainWindow.Show() (again show mainWindow).On mainWindow user selects another item from the ListBox and clicks "Show" - the form1 is shown and it should display new data because user selected new item on mainWindow but form1 displays old data (data which was shown when module for form1 was loaded for the first time).
Example - on mainWindow we have the ListBox with the list of offices of some company, we select "Office1" and click "Show", this mainWindow hides and form1 loads, form1 displays the expenses list for "Office1". When I select another office on mainWindow, e.g. "Office2" form1 should display expenses for "Office2" but it displays expenses for "Office1".
I do moduleManager.LoadModule("") when user clicks "Show" button on mainWindow. I found the information that we can't reload module, it means the module is loaded only when we click "Show" button for the first time, but how can we update the data on the view?
I am not sure I completely follow, but I will take a stab at this.
CreateShell should be for your main window only. Prism uses this to setup the very first window for the application. The only reason I have seen to make more than one visual window in here is for a splash screen.
So have CreateShell make your MainWindow. Then, have MainWindow create your other forms as needed. If you need new data each time, you can new them up each time.
The LoadModule part of your question is also a bit confusing. The ModuleManager is a way to allow you to get parts of your application without needing a hard reference it.
Related
I have a user control sitting on my main window, It is a menu.
When a user tries editing objects on a page I want to disable this user control while the user is on edit mode so they do not navigate off the page they are editing.
I am having trouble accessing the user control(placed on the main window) from a page
User Control Name - MenuView
The code below is on the page load of the page
MainWindow mainWindow = new MainWindow();
mainWindow.MenuView.IsEnabled = false;
This does not seem to work though
You need to get a reference to the existing instance of the MainWindow instead of creating a new one.
If you don't care about MVVM, the easiest way to do this would probably be to use the static Application.Current.Windows or App.Current.MainWindow property:
MainWindow mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
if (mainWindow != null)
mainWindow.MenuView.IsEnabled = false;
Note that this approach does create a coupling between your classes, but this is inevitable if you access a field of the window from in the Page class.
You probably want to look into the MVVM design pattern but that's another story.
I have a wpf application which will work minimized. The application will show a second window when system wakes up from sleep. In the second window there is a combobox and a button. when i click on the button it should set the value of a variable in the mainwindow with the value of combobox. But the problem is the variable in mainwindow is not accessible in second window. How to do this?? I searched a lot in net. But unable to find a working solution. Any suggestions??
You could use Event / delegate approach to get it:
A code snippet to sum-up:
In your First window when creating the second one do
Window1 win = new Window1();
win.GetEvent += win_GetEvent;
win.ShowDialog();
And in the second window you have:
public object ValueToGet;
public delegate object GetValueDelegate(object _value);
public event GetValueDelegate GetEvent;
public Window1()
{
InitializeComponent();
GetEvent.Invoke(ValueToGet);
}
Well I don't know which your specific requirment but just to intreduce the approach
I am developing WPF application which contains MainWindow.xaml as container to display all user controls inside the Mainwindow .I have defined all the menus inside the Mainwindow.xaml and displaying the respective usercontol inside mainwindow.xaml grid.
Below is my Mainwindow grid definition and respective codebehind event handler code
<Grid x:Name="Container" Grid.Column="0" Width="0" Margin="0,0,0,10" Visibility="Visible">
</Grid>
Code Behind Menu click Event Handler
When the maindow is loaded after login it will call and display the CustomerListView user control
private void Window_Loaded(object sender, RoutedEventArgs e)
{
CustomerListView CLView = new CustomerListView ();
Container.Children.Clear();
Container.Children.Add(CLView );
Container.Children[0].SetValue(WidthProperty, CLView.Width);
Container.Children[0].SetValue(HeightProperty, CLView.Height);
}
//Customer Menu Click Event
public void NewCustomer_Menu_Click(object sender, RoutedEventArgs e)
{
//AddCustomer is User control
AddCustomer AddEmployeeObject = new AddCustomer();
Container.Children.Clear();
Container.Children.Add(AddEmployeeObject);
Container.Children[0].SetValue(WidthProperty, AddEmployeeObject.Width);
Container.Children[0].SetValue(HeightProperty, AddEmployeeObject.Height);
}
Everything works fine until i integrate my application by new login control.After successful login i displayed mainwindow. If i am doing some actions like adding new customers(separate user control) or editing new customers(seperate user control) my application get closed automatically.How to overcome this issue?
Code to display mainwinow after logged in
if (IsValidUser)//Bool variable to validate user
{
//Hide the Loginwindow
this.Hide();
//Display mainwindow
MainWindow objMainWindow = new MainWindow();
objMainWindow.ShowDialog();
}
If i do any update or insert operations it closes the application after insert or update or refresh.
It seems every time Maindow is reloads after the insert or update or trying to load another user control or refresh the user control inside the mainwindow grid.How to resolve this?
You are clearing your Grid named Container every time you add a new Customer object by calling Container.Children.Clear(). Don't add new controls in code behind, instead define your UI in XAML and use data binding to visualize the objects you are adding.
Some links for you to read:
Data Binding Overview: http://msdn.microsoft.com/en-us/library/ms752347(v=vs.110).aspx
ObservableCollection: http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx
Woha !!! Got the solution finally. I have defined the button with IsCancel="True" property.So when ever i submit the data it closes the Mainwindow.It's just the copy paste mistake and finally removed the IsCancel attribute and works fine.
Background:
I have WPF application with a main window containing a user control. I want to pass a value from the main window to the user control.
In the Main window's constructor I have code:
public MainWindow()
{
InitializeComponent();
_vm = new MainWindowViewModel();
this.DataContext = _vm;
ucControl = new UserControl1("NameSet");
}
(ucControl is my user control)
User control has two constructors:
public UserControl1()
{
InitializeComponent();
this.ID = ID.GetNewID;
}
public UserControl1(string name)
{
InitializeComponent();
_vm = new UCViewModel(name);
this.DataContext = _vm;
this.ID = ID.GetNewID;
}
The problem is: although the second constructor (with parameter) is called, it is not loaded in the main window. I checked the ID (this.ID) in the user control's loaded event and I see the ID set in the default constructor and its DataContext is null. Because of this reason, I do not get the "name" string in my user control.
Any help please? Since I am using MVVM pattern I do not want to expose properties in user control (view) to be set from main window just for this.
You are instantiating the UserControl1 object twice:
Once within the XAML. The <uc:UserControl1> element instantiates a UserControl1 object, using the default constructor, and assigns it to the member ucControl.
You instantiate it again within the constructor of the MainWindow object
If you put a break point in the constructor of UserControl, you'll notice it is called twice. I assume WPF instantiate and initialize the XAML's UserControl (#1 from above) after you assign the dynamic UserControl (#2 from above), and this is why you see the former in the logical tree of MainWindow.
You should have only one instance. If you want to parameterized a user control, the canonical paradigm is what you mention that you don't want to do (why??). If you had such a property, you could set it in the XAML: <uc:UserControl1 x:Name="..." YourProperty="NameSet>
exposing such a property is a single line in the UserControl:
public YourProperty { get; set; }
If you insist of not having this line, you should do the following:
Remove the XAML's user control.
In main window, subscribe to the Loaded event
In the handler of the Loaded event, instantiate a new UserControl1 - with whatever constructor parameter that you want.
Manually add it to the Children array of the parent Grid element
Clearly this isn't my recommendation. In addition to the complexity, with the former method you'll also work very well with the Visual Studio designer.
I have a MDI-Parent Form with many ChildForms, when I want to add a control on my Parent form, Child form appears under the control, For example I want to add a groupbox and a PictureBox on MDIParent Form, but when I call the Child Form it appears Under these controls.
frmChildForm1.TopMost=true doesn't works either.
I have attached a photo for more description.
What can I do?!
but I want to have an Image as Background
That's possible, you can set the BackgroundImage property of the MDI client control. The only obstacle is that you cannot directly get a reference to that control. You have to find it back by iterating the form's Controls collection. Like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
foreach (Control ctl in this.Controls) {
if (ctl is MdiClient) {
ctl.BackgroundImage = Properties.Resources.Lighthouse;
break;
}
}
}
}
Where Lighthouse was a sample image I added as a resource. Change it to use your own. Another common technique is to subscribe the Paint event for that control and draw whatever you want. A gradient is a common choice.