I am a very newbie on WPF, C#, and Kinect. But I've found out how to initialize the kinect, and show two windows. My application is a toy one, have a full screen app with a button, when the user clicks, it should open a new window.
I've tried but two things won't work:
when the new window open the kinect user view won't show any body
when closing the window (going back to the main) the app crashes
The prototype window XAML is like this:
<Window ...>
<k:KinectRegion Name="region_">
<Grid>
<k:KinectUserView .../>
</Grid>
</k:KinectRegion>
</Window>
On the C# side, I have a prototype class like this:
public partial class MainWindow : Window
{
public KinectSensor sensor_ = KinectSensor.GetDefault();
public MainWindow()
{
//...
KinectRegion.SetKinectRegion(this, region_);
this.sensor_.Open();
}
}
The secondary page (with identical constructor as above) has a button that calls a function that basically says sensor_.Close() and this.Close().
Can I use a single kinect with multiple windows? In case not (please tell me I can!) how can I proceed in having two "views"? Pages AFAIK reading on the web, requite NavigationWindow, and VS complains I cannot add the kinect region to that.
Thanks!
It turns out you don't need to close the sensor. In order to make more windows work with one sensor:
pass the KinectSensor initialized in the main one to the "child" window
initialize the child's region
You just need to this.Close() without ever opening again the stream or closing it. The Kinect user view works flawlessly.
Related
Edit: Please see my comment below - the code itself seems to be correct (at least the Prism region code) but navigation in the new window instance is still not working.
To start off with, here is the issue I'm having...
I have a main window with a menu bar that switches views in the main window to take the user to different screens. This is all working great.
So I thought today that I would add a 'first time user' screen to handle all the initial setup for the application. This is a new window that will pop up if certain first time properties haven't been set and welcome the new user, get the initial setup complete, etc. I wanted to have navigation on this new window in a new region (just next and back buttons that take the user through the setup).
I thought this would be easy but after 3 hours of floundering and searching the darkest corners of the web I am still very confused - I also looked at Brian Lagunas' Pluralsight videos on MVVM but nothing I have tried to apply is working to setup navigation on the new window.
The content region for the main window is named "ContentRegion" and the content region for the new window is named "SetupRegion".
All views are registered in the bootstrapper like so:
// All views must be registered.
Container.RegisterTypeForNavigation<Home>( "Home" );
Container.RegisterTypeForNavigation<Index>( "Index" );
Container.RegisterTypeForNavigation<Settings>( "Settings" );
Container.RegisterTypeForNavigation<FirstTimeSetupWelcomeScreen>( "WelcomeScreen" );
Container.RegisterTypeForNavigation<FirstTimeSetupScreen2>( "FirstTimeSetupScreen2" );
Here is how the new window is being instantiated currently, from the main window:
public MainWindowViewModel(IRegionManager _regionManager, EventAggregator _eventAggregator)
{
eventAggregator = _eventAggregator;
regionManager = _regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
// Set the default view to the home screen
regionManager.RegisterViewWithRegion("ContentRegion", typeof(FirstTimeSetupWelcomeScreen));
// Check to see if program is in first time run or not
if ((ConfigurationManager.GetSection("SaveLocationsGroup/Locations") as IndexLocationsSection).SaveLocation.Location == "")
{
var firstTimeWindow = new FirstTime();
firstTimeWindow.Show();
// Set the default view to the welcome screen on new window
regionManager.RegisterViewWithRegion("SetupRegion", typeof(FirstTimeSetupWelcomeScreen));
}
}
In the XAML for the new window, the content control is setup like this:
<Grid>
<ContentControl prism:RegionManager.RegionName="SetupRegion" />
</Grid>
I have tested by replacing the code in the Navigate command on the main window and having it to navigate to the new user controls, showing them in the main window and that works.
However, in the new window they are not and I can't seem to figure out why. I have also tested to see if the button in the first/default user control view model is firing correctly and it is - for reference, here is that Navigate command code:
private void Navigate(string uri)
{
// WriteLine command to test the button firing
Console.WriteLine(uri);
regionManager.RequestNavigate("SetupRegion", uri);
}
Lastly I've placed the first view inside the main window and it seems to fire correctly, changing the content in the main window - I just can't get it to work or anything to work on the new window at all no matter how I try it. I'm assuming that there is something that I don't know that has to do with either navigation on new instances of windows (aside from the main window) or having to do with containers and new windows but I haven't been able to figure out what. Thank you guys for all of your assistance as always.
It turn out Brian Lagunas has a course on multiple shells I should hopefully be able to use to accomplish what I need. I will attempt to use it.
I'm trying to create an application that would use multiple windows. For starters I'd like it to have a splash screen window and a "main window". I came along this article: http://southworks.com/blog/2010/01/26/creating-a-multi-shell-application-in-prism-v2/ however it doesn't seem to suit my needs. Author is creating 2 windows at the same time, also showing both right from the start. What I want to do is to create this splash screen window (with some nice loading indicators) and only when it's underlying logic will complete its tasks, I want to show another window
protected override DependencyObject CreateShell() {
//return Container.Resolve<MainShell>();
return Container.Resolve<SplashScreenShell>();
}
protected override void InitializeShell() {
base.InitializeShell();
App.Current.MainWindow = (Window)Shell;
App.Current.MainWindow.Show();
}
Another issue is that when I use this code, all my modules (so even those used only by MainShell) are getting loaded and initialized, and that's totally not what I want. Mainly because Prism looks for RegionName that is not present on SplashScreenShell (but is present on the second shell).
I'm using Prism 6.1.0 and .NET 4.6.
Why not just show your splash screen before you call MainWindow.Show? Just show it as ShowDialog to stop the bootstrapper form continuing to process until you close your splash screen.
protected override void InitializeShell()
{
var sc = new SplashScreen();
sc.ShowDialog();
App.Current.MainWindow = (Window)Shell;
App.Current.MainWindow.Show();
}
The good patern is to stick to one window for the whole application. My proposal is to create splash screen as UserControl and then kind of mess around with visibility.
Your MainView may be looking as follows
<Grid>
<ContentControl Content="{Binding CurrentViewModel}"/>
<userControl:SplashScreen/>
</Grid>
At this point your splash screen covers view and once the view is loaded you make the SplashScreen invisible. In order to do so create another class which will expose boolean property like IsVisible, and method Show/Hide for making splash screen visible and invisible respectively. Subsequently, you set SplashScreen's DataContext to that class, bind Visibility property to IsVisible and make use of BooleanToVisibilityConverter, provided by WPF by default. For appearance sake, you can set splash sreen opacity to, for instance 0.75, so that it would show through splash screen displaying some destination view simultaneously.
Whenever you want to show splash screen you invoke Show method, within method you set IsVisible to true, PropertyChanged event is raised and changes are reflected at view. As a result Visibility is set to true and Splash screen shows up on the top covering everything else.
If you follow these steps you should acquire similar outcome. Message being displayed can be explicitly adjusted as well, as a replacement for hardcoded "Loading".
I need to close a modal window from a ViewModel based on a click command that is triggered in a control that is presented within the window.
So, I have MainViewModel, JimViewModel, JimWindow and JimControl. MainViewModel creates a JimWindow and sets its DataContext to JimViewModel. JimWindow contains JimControl, which contains a button. When this button is clicked, I'd like to trigger a command that somehow closes JimWindow.
I've seen a few questions that answer this with respect to closing the Window from the actual Window (By passing the instance of the Window to a Command on the ViewModel), but it doesn't translate to what I want to do.
I'm not using a framework so I have no handy messenger to assist me. Can anyone help? Is it a case of somehow referencing the Name of the parent window from the control?
MainViewModel should not be creating windows, at least not directly. VMs should only create VMs. A window is part of the view world.
If you need your JimVM hosted in a window, then it would be better to have some kind of WindowService abstracted away behind an interface. MainVM then just creates JimVM and gives it to the window service to host in a window
Once you've got the windows bit decoupled into a separate service, then you can do all your crufty window stuff in there. I would have JimVM expose a CloseCommand and a Closed event. You can bind your JimControl button to the CloseCommand, and the windows service can subscribe to the Close event, and tear down the window when it fires.
This keeps the view and VM stuff completely separate. The only thing that knows how to glue the two together is the window manager.
Although idea of ViewModel creating a View sounds a little backwards, you could use messaging, e.g. TinyMessenger or Messenger that comes with MVVMLight.
You could then register for a message in your View/ViewModel and send it from-anywhere. A really simplistic example using MVVMLight could be:
// custom message
public class CloseMessage : MessageBase
{
public CloseMessage(object sender)
:base(sender)
{}
}
// main view registers for a message
public partial class MainWindow : Window
{
public MainWindow()
{
Messenger.Default.Register<CloseMessage>(this, message =>
{
// do teh stuff
});
}
...
}
// command bound to close button sends the message
private void YourCloseMainViewCommand()
{
Messenger.Default.Send(new CloseMessage(this));
}
i want to make Form loading a splash screen with transparent background and a non rectangular shape with is click-through-able. is this possible ? how it's made ?
i was wondering if there is a way of making the Form1 calling a WPF window ( as a kind of splash screen ) within the same vs project.
i've tryed to rightclick the project in the project-explorer in VS -> add and then i was searching for WPF window. but the only thing that i am able to add is a "wpf User Controll".
so far so good, but if i start the application then, it gives me an error saying i should ad a reference to System.Windows.markup.IQueryAmbient, but i cant find it in the list ( .NET )
what am i doing wrong ? what is the propper way to implement a WPF window into a Forms application project ?
thanks for all suggestions.
EDIT:
this is the splash screen of Adobe Flash Professional CS6, and it pretty much explains exactly what i want to have. a non rectangular image with semi-transparent and full-transparent parts in it
http://webalazar.com/wp-content/uploads/2012/09/Adobe-Flash-Professional-CS6.png
There's 3 ways to do this:
1.) go completely WPF and then reference the WinForms .NET libraries in your WPF application if you want WinForms specific stuff
2.) Create a new WPF library (a .NET dll that can be referenced in your code) that has all the WPF functionality you want in it (like your splash screen), then create a new WinForms .NET app and reference the WPF project in your WinForms project then call your WPF library from your WinForms app
3.) Depending on what your trying to accomplish (like special graphics windows or other 'fancy' UI stuff), and how much time/effort you're willing to put into it, you could learn DirectX, or use the 'gdi32.dll' and import it's GDI+ functionality.
EDIT:
So here's a step by step to get a WPF splash screen in a WindowForm C# app:
1.) Create a new C# Windows Forms appliction, call it whatever you want and save it wherever you want
2.) File->Add->New Project
3.) Add a new C# WPF User Control Library, call it SplashScreen and be sure to note that it will try and save it under the same file location, so if you want to save it else where be sure to choose a different location.
4.) Delete the default 'UserControl1.xaml' that's created in the SplashScreen WPF library
5.) Right click the WPF project and 'Add->Window', then name it SplashScreen.xaml
6.) Replace all of the exisiting code in SplashScreen.xaml with the following:
<Window x:Class="SplashScreen.SplashScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle="None" Background="Transparent" AllowsTransparency="True"
ShowInTaskbar="False" SizeToContent="WidthAndHeight"
Title="SplashScreen" WindowStartupLocation="CenterScreen">
<Image Source="logo.png" Stretch="None" />
</Window>
7.) Right click the WPF project and 'Add->Existing Item', make sure your file filter is set to 'all files' and choose your 'logo.png'.
8.) View the properties of the newly imported 'logo.png' and make sure its 'Build Action' is set to 'Resource'
9.) In your Windows Forms project right click 'Add->New Reference', select the 'Projects' tab and select the 'SplashScreen' WPF project you just created.
10.) In your Windows Forms project right click 'Add->New Reference', select the '.NET' tab and select the 'PresentationFramework','PresentationCore', 'WindowsBase' and 'System.Xaml' libraries.
11.) In your 'Program.cs' file in your Windows Forms project, you can now do this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace MyGame
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Create a new 'splash screen instance
SplashScreen.SplashScreen ss = new SplashScreen.SplashScreen();
// Show it
ss.Visibility = System.Windows.Visibility.Visible;
// Forces the splash screen visible
Application.DoEvents();
// Here's where you'd your actual loading stuff, but this
// thread sleep is here to simulate 'loading'
System.Threading.Thread.Sleep(5000);
// Hide your splash screen
ss.Visibility = System.Windows.Visibility.Hidden;
// Start your main form, or whatever
Application.Run(new Form1());
}
}
}
Create a Windows Form
set its FormBorderStyle to None
set its TransparencyKey to #00FF00
set its BackgroundImage to a png image with unwanted area colors set to #00FF00
done!
when you load an image as background image for your form, it will compare every pixel of it with the transparency key, if it was a match, then it will render that pixel as transparent.
I am new to desktop application development and have a pretty basic question. I have a WPF form named MainWindow, how should I go about having multiple pages on this, such as "User Management", "Manage Content" etc..
I think I have the following options:
Use multiple forms
Tabs
Group Box?
Any clarification would be great!
Well in my most recent application I started by using a TabControl, that's a safe and rather easy way to go.
Recently switched the tabcontrol with a StackPanel with a series of Expanders inside. I styled the expanders to have them display the header vertically and expand horizontally... somewhat similar to the first xbox dashboard. And it looks and works great! =)
Another alternative would be to use a Page instead of a window... Then you would just have to Navigate to each different page.
EDIT:
Here's an example of a multi-page application... might be close to what you need.
The solution I went with that suited what I was looking for was using WPF Pages but thanks for your answers.
There are many ways to do that, such as creating UserControl and show them in the run time.But using TabControl is fast and safe.
Just Use TabControl and place your pages in tab items .Then hide the header of TabControl by setting the value Visibility="Collapsed" to each TabItem.
The result is as below:
As you see the headers are hide and you can switch to each page you want.
Create
usercontrol(wpf): UserManagement
usercontrol2(wpf) : ManageContent
place control "ContentControl" in the main window
Run the code on click of button:
//Displays usercontrol1
contentControl.content = new UserManagement();
//Displays usercontrol2
contentControl.content = new ManageContent();
Hope this helps you.
I'd like to give you an example of something I have in one of my applications.
The app has two windows: the main window and another one (also derived from Window and equipped with the appropriate buttons and event handlers) that is used as a start dialog. The start dialog is called in the constructor of the main window like this:
public partial class MainWindow : Window
{
startdlg m_dlg;
// ...
public MainWindow()
{
m_dlg = new startdlg();
if ((bool)m_dlg.ShowDialog())
{
// ...
}
else
{
Close();
}
// ...