I have created a user control in wpf. I have also create a mainwindow. Now, what i want is that, when i click on a button (which is in mainWindow), a user control is shown like a dialog box. suppose i have a button named i-e create new user. Now, what i want is to show the control (that i have created for new user) on button click whithout calling it in mainWindow.
In the WPF demo application Family Show, user controls are created in the main window (MainWindow.xaml)
<!-- New User Control -->
<local:NewUserControl x:Name="NewUserControl"
HorizontalAlignment="Center" VerticalAlignment="Center"
AddButtonClick="NewUserControl_AddButtonClick"/>
Then in the code behind (MainWindow.xaml.cs), the different user controls are hidden or shown as a result of click actions from the button.
/// <summary>
/// Hides the New User Control.
/// </summary>
private void HideNewUserControl()
{
NewUserControl.Visibility = Visibility.Hidden;
DiagramControl.Visibility = Visibility.Visible;
enableButtons();
if (family.Current != null)
DetailsControl.DataContext = family.Current;
}
/// <summary>
/// Shows the New User Control.
/// </summary>
private void ShowNewUserControl()
{
HideFamilyDataControl();
HideDetailsPane();
DiagramControl.Visibility = Visibility.Collapsed;
WelcomeUserControl.Visibility = Visibility.Collapsed;
if (PersonInfoControl.Visibility == Visibility.Visible)
((Storyboard)this.Resources["HidePersonInfo"]).Begin(this);
NewUserControl.Visibility = Visibility.Visible;
NewUserControl.ClearInputFields();
NewUserControl.SetDefaultFocus();
... //Removed for brevity
}
I encourage you to download the Family Show app to look at the source code, or to browse it at least on-line.
You could put it in a separate window like Johannes Hofmeister suggested with his answer.
The main advantage of a User Control is that this user interface block might be used at multiple points in an application. (eg. a graph control user control with scroll, zoom and screenshot buttons would appear next to every graph, making it an ideal candidate for a user control).
You can easily add another window with the your usercontrol on it!
First, create another window (right click in the solution explorer, add new item, Window).
Second, drag you usercontrol onto the window:
<Window x:Class="MyWpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:DeleteMeTest="clr-namespace:DeleteMeTest"
Title="Window1" Height="300" Width="300">
<Grid>
<MyWpfApplication:UserControl1 />
</Grid>
</Window>
Then you must setup the button click handler to show the window:
MainWindow.xaml:
<Window x:Class="MyWpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Click Me" Click="Button_Click"/>
</Grid>
</Window>
The Button_Click Handler in MainWindow.xaml.cs:
private void Button_Click(object sender, RoutedEventArgs e)
{
new Window1().ShowDialog();
}
The ShowDialog() Method opens a dialog, which means that the window comes on top and must be interacted with (Closed) before you can return to interacting with your main window.
You can also use the Show Method, to have a non blocking window.
Related
I created a user control in a project that consists of just a MainWindow.xaml and the code behind. I added the .dll to the toolbox of VS, and dropped it onto a window in a new project. This created the following:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication5"
xmlns:ThinkGeoClean="clr-namespace:ThinkGeoClean;assembly=ThinkGeoClean" x:Class="WpfApplication5.MainWindow"
mc:Ignorable="d"
Title="MainWindow" >
<Grid>
<ThinkGeoClean:ListBoxCustom x:Name="listBoxCustom" />
</Grid>
</Window>
The ThinkGeoClean is the name of the .dll I added which is the usercontrol. ListBoxCustom is just a public class in the control, but is NOT what I want to show. I want to show the main window of the usercontrol (not a window), but it doesn't show as an option after typing <ThinkGeoClean:. The only thing that shows up is ListBoxCustom. If I go ahead and type <ThinkGeoClean.MainWindow>, it gives a XamlParseException error on that line.
Now, if I go into the code-behind and do:
ThinkGeoClean.MainWindow newWin = new ThinkGeoClean.MainWindow();
newWin.Show();
It will pop up the usercontrol in a new window and it works fine.
Here's the beginning of usercontrol code behind:
namespace ThinkGeoClean
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
And the xaml for it is just a single grid containing some buttons and a map control.
Edit: In addition to the answer below, my user control was originally just a normal WPF project. I thought changing the output type to a class library would change it into a user control automatically, but I actually had to go into the xaml and change the the into .
This XAML:
<Grid>
<ThinkGeoClean:ListBoxCustom x:Name="listBoxCustom" />
</Grid>
...is not equivalent to creating an instance of a window and call the Show() method on it programmatically.
Instead the XAML processor will try to add the window to the Children collection of the Grid and this is not possible since a window cannot be child of another control. That's why you get an exception.
Also, a UserControl must be hosted in a window or page. It is not a top-level control that you can display without any parent host.
hello i am having some problem while using user control in wpf. i have single image in user control . i want to place this user control on my main window which contains some map.i am placing this user control(image) on my main window.they are 10 t0 15 .what i want is to open different windows by clicking on this usercontrol which is just an image . but when i do that it show me only same window every time . is there any way so i just have to create single user control and use it multiple times to open different windows .like (window1,window2,window3) etc..
kindly help me . i will be really thankfull.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Demo.WindowsPresentation.CustomMarkers.CustomMarkerDemo"
Height="40" Width="30" Opacity="10">
<Image MouseDown="clickit" Name="icon" Source="bigMarkerGreen.png" VerticalAlignment="Center" HorizontalAlignment="Center" />
In cs
this.MouseDown += new MouseButtonEventHandler(clickit);
void clickit(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("test");
main.show();
}
As far as I could understand by the given information, you want to open this UserControl in different windows. I would suggest you to create a window and add this UserControl onto it like
<Window x:Class="Demo.WindowsPresentation.CustomMarkers.win.winCustomMarker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:marker="clr-namespace:Demo.WindowsPresentation.CustomMarkers"
Title="Window" Height="345" Width="380">
<Grid>
<marker:CustomMarkerDemo></marker:CustomMarkerDemo>
</Grid>
</Window>
And then in your mouse click event:
void clickit(object sender, MouseButtonEventArgs e)
{
winCustomMarker customMarkerWindow = new winCustomMarker();
//bind any information you want that you want to pass to your inner UserControl
customMarkerWindow.show();
}
You may consider launching them as separate processes. Move user control to a new WPF project(.exe) and from main app create as many instances of user control you need.
var imgUserControlProcess = new ProcessStartInfo
{
FileName = "ImageUserControl.exe",
UseShellExecute = false,
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Normal
};
var processStart = new Process
{
StartInfo = mainViewProcess
};
processStart.Start();
So iv looked around for a bit and found out that MDI is obselete for WPF, Basically what i am trying to do is show a specific page in a grid object on load, and once a menu item from my drop down menu is selected, the content of the grid will be changed to the content from a different page (this is depending on which menu item is selected).
To go into more detail (perhaps this will help) The area where the window will be shown will need to have the window with no borders, or titles, or buttons to minimize/close etc.. only showing the content of this window, it won't be resizeable but fixed, i have a menu of which as i said earlier, when a different menu item is clicked, the relevant window should be displayed in the fixed area. Additionally if any buttons or events inside this content that is displayed happen (i.e a button causes a different window to show for example) then the content in the fixed area should be replaced by this new window's content
This is the first time i have done something like this and from what i've read it sounds like this is something very tricky for a WPF application, I hope i can get some sort of insight or direction i should be going so that i can make this possible.
Thanks.
You can try for example ChildWindow from Extended WPF Toolkit Community Edition.
Edit #1:
But whenever i try to create a WindowContainer in the Xaml it has
problems with the namespace prefix with "xctk:WindowContainer" so
how do i create the appropriate namespace prefix to use it?
You have to add that namespace:
xmlns:xctk=http://schemas.xceed.com/wpf/xaml/toolkit
For example:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
Title="MainWindow" Height="350" Width="525">
<Grid>
<xctk:WindowContainer>
<xctk:ChildWindow Height="100" Width="250" Left="10" Top="10">
<TextBlock Text="Hello World ..." />
</xctk:ChildWindow>
</xctk:WindowContainer>
</Grid>
</Window>
Edit #2:
You can of course change some properties (for example):
<xctk:ChildWindow
Height="100"
Width="250"
Left="10"
Top="10"
Name="chWindow"
CloseButtonVisibility="Hidden"
WindowStyle="None"
BorderThickness="0">
Edit #3:
Ok yeah, so with everything referenced it is giving me errors still..
Try it simpleā¦ Create Wpf Application, add Extended WPF Toolkit 2.4 NuGet package, in MainWindow.xaml add previous code and in MainWindow.xaml.cs add next code:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.chWindow.Show();
}
}
}
I am just in the process of teaching myself WPF. I have reached the point of adding controls dynamically and have hit a brick wall on something really simple. I code that should create a button (shown below):
Button button = new Button() { Height = 80, Width = 150, Content = "Test" };
parentControl.Add(button);
My question is what is parentControl actually called? I am using the standard Visual Studio 2012 WPF template and my main window is called MainWindow. I have no objects in the Window besides what comes in the template
So far I have looked at:
WPF runtime control creation
Dynamic control creation in WPF
WPF MVVM Dynamic control creation
Dynamic creation of control
Where should I put WPF specific code when using MVVM?
Steps Of Control Creation Process WPF
Where to put code in (primarily) windowless WPF app?
The closest I have found it: WPF runtime control creation.
All of these questions just assume you know such a basic thing but I don't. Please help.
I think I understand your question. If your XAML code looks like:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
</Window>
Then your codebehind should be something like:
public MainWindow()
{
InitializeComponent();
Button button = new Button() { Height = 80, Width = 150, Content = "Test" };
//In case you want to add other controls;
//You should still really use XAML for this.
var grid = new Grid();
grid.Children.Add(button);
Content = grid;
}
However, I warmly suggest you to use XAML as much as you can. Furthermore, I wouldn't add controls from the constructor but I'd use the Loaded event of the window. You can add a handler to the event in codebehind from the constructor, or directly in XAML. If you wanted to have the same result as above in XAML, your code would be:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Height="80" Width="180" Content="Test"/>
</Grid>
</Window>
I'm new in WPF and C#. I know a lot of VB.NET and I'm used to the way when I call a form object like textboxes, etc. I'm calling it from another form. Now, I'm using WPF, I'm confused. Because I have a Main Window. And I want to add and item to a listbox in the Main Window from a Class. In VB.Net , its just like this.
IN FORM2
Form1.Textbox.Text = "";
Wherein I can't do it in WPF. Can someone please Help me. Thanks!
WPF windows defined in XAML have their controls publicly accessible from other classes and forms, unless you specifically mark them with the x:FieldModifier attribute as private.
Therefore, if you make an instance of your main window accessible in another class, be it a Window or anything else, you'll be able to populate controls from within this second class.
A particular scenario is when you want to update the contents of a control in your main window from a child window that you have opened on top of it. Is such a case, you may set the child window's Owner property to the current, main window, in order to access it while the child is visible. For instance, let's say you have defined these two windows:
// MainWindow
<Window x:Class="TestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox Name="mainListBox" Height="250" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
<Button Content="Open Another Window" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="20" Click="OpenAnotherWindow_Click"/>
</Grid>
</Window>
and
// AnotherWindow
<Window x:Class="TestApplication.AnotherWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AnotherWindow" Height="300" Width="300">
<Grid>
<Button Content="Add New Item to Main Window" HorizontalAlignment="Center" VerticalAlignment="Center" Click="AddNewItem_Click"/>
</Grid>
</Window>
each in its own XAML file.
In MainWindow's code behind, inside the button click handler, you show an instance of AnotherWindow as a dialog and set its Owner property to MainWindow's instance:
private void OpenAnotherWindow_Click(object sender, RoutedEventArgs e)
{
AnotherWindow anotherWindow = new AnotherWindow();
anotherWindow.Owner = this;
anotherWindow.ShowDialog();
}
Now, you can access the MainWindow's instance from AnotherWindow's Owner property, in order to add a new item to the ListBox control defined on it, in the button click handler in AnotherWindow's code behind:
private void AddNewItem_Click(object sender, RoutedEventArgs e)
{
MainWindow mainWindow = Owner as MainWindow;
mainWindow.mainListBox.Items.Add(new Random().Next(1000).ToString());
}
It simply adds a new random number to the ListBox, in order to show how the code accesses and modifies the control's data in MainWindow.
Pure WPF solution, but also may be easiest in your case, is using a Data Binding in WPF.
Every form's control is binded to some data on ModelView (pure MVVM approach) or to data (more or less like yuo can do it in WindowsForms). So the "only" thing you have to do is to read/write data binded to controls on UI of that form.
For example, you have TextBox on Windows and want to read a data from it.
This TextBox is binded to some string property of the class that is responsible for holding the data for the controls on that form (just an example, in real world could be 1000 other solutions, based on developer decisions). So what you need, is not to say: "window give textbox" and after read TextBox's content, but simply read binded string property.
Sure it's very simply description of a stuff. But just to give you a hint. Follow databinding link provided above to learn more about this stuff. Do not afraid of a lot of stuff there, it's after all is not a complicated idea and also pretty intuitive. To make that stuff to work in simply case you will not need to make huge efforts by me. The stuff becomes really complex when you end up into real world applications.
This will get all active windows:
foreach (Window item in Application.Current.Windows)
{
}