I'm trying out sharpdx tookit with universal app in windows 10 and can't get the input to work. I know I have to create different input for different devices but for now I just want to try keyboard.
So I follow this link first to set up the project: Is there a SharpDx Template, for a Windows Universal App?
And right now I'm trying input like I usually do it:
In the constuctor:
_keyboardManager = new KeyboardManager(this);
In the update method:
var state = _keyboardManager.GetState();
if (state.IsKeyDown(Keys.B))
{
//do stuff
}
But he never register that the key B is down (or any other key I have tried). I have also tried GetDownKeys() but the list is always empty.
So does any one have any idea what to do here?
And there's an another, better, easier version:
using Windows.UI.Core;
using SharpDX.Toolkit;
using Windows.System;
namespace Example
{
class MyGame : Game
{
public MyGame()
{
CoreWindow.GetForCurrentThread().KeyDown += MyGame_KeyDown;
}
void MyGame_KeyDown(CoreWindow sender, KeyEventArgs args)
{
System.Diagnostics.Debug.WriteLine(args.VirtualKey);
}
}
}
You have to subscribe to the CoreWindow's event, that's it :)
HEUREKA!
I had the same problem, but with windows 8.1. It took me 2 days to find a solution. It's the foolish SwapChainPanel, which can't be in focus because the class doesn't inherit from Control class, so it won't handle keyboard events.
The solution is HERE that is to say, you have to put an XAML element that's inherited from the Control class, like Button to handle the event. My XAML file is like this:
<SwapChainPanel x:Name="_swapChainPanel"
Loaded="_swapChainPanel_Loaded"
KeyDown="_swapChainPanel_KeyDown">
<Button x:Name="_swapChainButton"
Content="Button"
HorizontalAlignment="Left"
Height="0"
VerticalAlignment="Top"
Width="0"
KeyDown="_swapChainButton_KeyDown">
</Button>
</SwapChainPanel>
In the XAML.cs I handled the events this way:
private void _swapChainButton_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
e.Handled = false; //This will pass the event to its parent, which is the _swapChainPanel
}
private void _swapChainPanel_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
game.KeyboardEvent();
}
In the KeyboardEvent() method I put the if things... and you have to make the button in focus manually, with code. "_swapChainButton.Focus(FocusState.Programmatic);"
But last, it's not so good for me, it's so slow. It has delay. :/
Related
I would like to add a click event, which sends information about the day, on the dayitem in the CalenderView in UWP. I'm having a hard time figuring out how.
[
I've already tried following, but it does not work and I can imagine that there's better ways to do it.
private async void KalenderView_DoubleTappedAsync(object sender, DoubleTappedRoutedEventArgs e)
{
Viewmodel.Calendar_ViewModel calender_Viewmodel = new Viewmodel.Calendar_ViewModel();
if ( KalenderView.SelectedDates != null )
{
await calender_Viewmodel.OpenNewWindowAsync();
}
else
{
}
}
}
and the XML:
<Grid>
<CalendarView
x:Name="KalenderView"
DoubleTapped="KalenderView_DoubleTappedAsync"
CalendarViewDayItemChanging="CalendarView_CalendarViewDayItemChanging" HorizontalAlignment="Center" Margin="0,0,0,0" VerticalAlignment="Center" Height="526" Width="936"
SelectionMode="Single"
DisplayMode="Month"/>
</Grid>
you can use SelectedDatesChanged event for this purpose it will be invoked whenever you change the date from the calender in any way and within this event you can see the new date of the calender which is currently selected and access, just the dayitem or any other properties on the calenderdayitem.
if you want to specifically add an event to when a day item can be clicked it can be a bit complicated, as you will have to create a control ( refer : Templated Control vs Custom Control in UWP. No clear answer found online ) but I suggest dont do that unless you have no other option and you know what you are doing.
I apologize if the question title isn't really specific, I'm not exactly sure how to condense the problem I'm having down to a few words. But to simplifiy the problem I'm having, here is my issue:
I'm creating a tool using WPF that consists of a TextBox that will contain a path to a directory and a Button that will allow you to Browse to a certain directory. Now, when I select the Browse button, it pops up a dialog, allows the user to select a directory and then I have some methods that will disable some buttons and updates some Brushes on the screen if the path doesn't meet a certain set of criteria. No problems there, got that working.
My problem is the TextBox that this Browse button correlates with. This TextBox is using a binding as such:
In my MainWindow.xaml (Yes, this is the simplified, focused version):
<Window>
<TextBox Text="{Binding Directory}" TextChanged="Directory_TextChanged" />
<Button Content="Browse..." Click="Browse_Click"/>
</Window>
In my code MainWindow.xaml.cs file:
public partial class MainWindow: Window
{
private ViewModel myViewModel;
public MainWindow()
{
myViewModel = new ViewModel();
this.DataContext = myViewModel;
}
private void Browse_Click(object sender, RoutedEventArgs e)
{
// Dialog stuff that's working
viewModel.Directory = dialog.SelectedPath;
}
private void InstallDir_TextChanged(object sender, TextChangedEventArgs e)
{
ValidatePath(); /* Disables/enables buttons and updates brushes based on validation. Also working */
}
private void ValidatePath() {/* */}
}
Like I mentioned earlier, the browse button works fine. I'm trying to figure out however, how I can get this to work if I type a directory alongside it. Because if I type something in the textbox, that would mean that inside of the InstallDir_TextChanged() function I would have to set viewModel.Directory, but since I have the INotifyPropertyChanged attached to this ViewModel, this function would get called recursively.
I tried doing the validation stuff within the viewmodel, but I couldn't figure out how to update the brushes/buttons in MainWindow if I did this. (Still relatively new to C# so I haven't learned the ins and outs yet. This is the first WPF tool I've been making from scratch, so just a disclaimer).
Would anyone have any ideas (or logic) I can approach to try and accomplish this? If there's any further clarification needed, that's not an issue. I don't need an exact definitive answer. Maybe some advice that could point me in the correct direction would definitely suffice. I don't have a problem trying to figure stuff out.
I'm using the WinForms version of <WebBrowser> in my WPF app, a la <WindowsFormsHost> because in general it works a lot better than the Windows.Controls version. However I have one problem that has to do with touch screens.
Normally I set the ManipulationBoundaryFeedback event handler on controls to immediately handle the event, thereby preventing any boundary feedback, and I've tried to do so with this code:
MainWindow.xaml
<WindowsFormsHost IsManipulationEnabled="True" ManipulationBoundaryFeedback="WindowsFormsHost_OnManipulationBoundaryFeedback">
<forms:WebBrowser />
</WindowsFormsHost>
MainWindow.xaml.cs
private void WindowsFormsHost_OnManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e)
{
e.Handled = true;
}
On ordinary WPF controls, generally speaking, this works. And what I mean by "works" is that if you use your finger on the touch screen and drag up or down, you don't get the effects of touch screen intertia; that is, it doesn't shift the entire window up or down once you hit the boundary.
Here's a picture to illustrate what's happening:
As you can see, if I drag down within the browser, it pulls the entire window with it. What can I do to prevent this?
Not sure if you still need this answer but to prevent this unnecessary behavior simply inherit WindowsFormsHost class and override OnManipulationBoundaryFeedback like this:
public class MyClass : WindowsFormsHost
{
// Override is optional to remove unnecessary behavior
protected override void OnManipulationBoundaryFeedback(ManipulationBoundaryFeedbackEventArgs e)
{
// uncomment this to use base class implementation
//base.OnManipulationBoundaryFeedback(e);
e.Handled = true;
}
}
Edited
I have made a small test and added this code for my control
protected override void OnManipulationBoundaryFeedback(ManipulationBoundaryFeedbackEventArgs e)
{
Debug.WriteLine("OnManipulationBoundaryFeedback");
}
private void MyControl_ManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e)
{
Debug.WriteLine("MyControl_ManipulationBoundaryFeedback");
}
and Output was the following
OnManipulationBoundaryFeedback
MyControl_ManipulationBoundaryFeedback
OnManipulationBoundaryFeedback
MyControl_ManipulationBoundaryFeedback
OnManipulationBoundaryFeedback
MyControl_ManipulationBoundaryFeedback
OnManipulationBoundaryFeedback
MyControl_ManipulationBoundaryFeedback
So you can see that OnManipulationBoundaryFeedback launched first and then it invokes ManipulationBoundaryFeedbackEvent handlers
You could turn off this behavior for the whole system:
Open registry ( run regedit command ) and set HKEY_CURRENT_USER\Software\Microsoft\Wisp\Touch Bouncing to 0;
if HKEY_CURRENT_USER\Software\Microsoft\Wisp\Touch not exist Bouncing item, add it( DWORD type, Not QWORD or String) and set it value to 0.
However, this is not a good approch, even if it solve my problem. Look at this manipulationboundaryfeedback-does-not-work-in-webbrowser-in-wpf.
I want to play a beep sound effect when the user clicks.
I have a beep.mp3 file added to the project (isn't in a folder). In it's properties I see Build Action is set to Content
and this MediaElement:
<MediaElement Name="beep" Source="beep.mp3" Volume="1" AutoPlay="False"/>
then I can't hear any sounds after this:
beep.Play();
I've build a simple example (following your code) and everything should be ok. Just to ensure that everything is all right I'll perform some checkups described below:
In XAML:
<Button x:Name="myButton" VerticalAlignment="Cener" Content="BEEP"/>
<MediaElement Name="beep" Source="beep.mp3" Volume="1" AutoPlay="False" MediaFailed="beep_MediaFailed" MediaOpened="beep_MediaOpened"/>
Code behind:
public MainPage()
{
InitializeComponent();
myButton.Click += (sender, e) => { beep.Play(); };
// this below checks if your file exists
if (Application.GetResourceStream(new Uri("beep.mp3", UriKind.Relative)) == null)
MessageBox.Show("File not Exists!");
}
private void beep_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
// Show Message when opening failed
MessageBox.Show("There was an error: " + e.ErrorException.Message);
}
private void beep_MediaOpened(object sender, RoutedEventArgs e)
{
// as it's subscribed in xaml, juts after opening the App you should hear beep
beep.Play();
MessageBox.Show("Media opened");
}
First - in Constructor I perform a check up if my beep.mp3 exist (check if I can get it as a resource stream). If everything is ok, there you shouldn't see a message. Then after a while you should see one of the messages (Failed/Opened). If opened, then you should also hear beep.mp3.
Just be aware that if you for example put beep.Play() just after InitializeComponent, then you probably won't hear it - that's becasue the media must be opened before it's played (of course normally there is no need to subscribe to that event if you don't need to, but if you are having problems then it's nice to know if the media was opened).
On the other hand I would probably follow WiredPraire suggestion (in comment) and used SoundEffect to play short sounds.
Hope this helps a little.
Had something similar in Silverlight project. Try to add it into Assets folder, set to Content/Resource and Copy always to output.
I would like to run some code onload of a form in WPF. Is it possible to do this? I am not able to find where to write code for form onload.
Judging by the responses below it seems like what I am asking is not something that is typically done in WPF? In Vb.Net winforms it is easy, you just go to the onload event and add the code that you need ran on load. For whatever reason, in C# WPF it seem very difficult or there is no standard way to do this. Can someone please tell me what is the best way to do this?
You can subscribe to the Window's Loaded event and do your work in the event handler:
public MyWindow()
{
Loaded += MyWindow_Loaded;
}
private void MyWindow_Loaded(object sender, RoutedEventArgs e)
{
// do work here
}
Alternatively, depending on your scenario, you may be able to do your work in OnInitialized instead. See the Loaded event docs for a discussion of the difference between the two.
Use the Loaded event of the Window. You can configure this in the XAML like below:
<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Your App" Loaded="Window_Loaded">
Here is what the Window_Loaded event would look like:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// do stuff
}
This question was asked 4 years ago, but this answer may help others too so here goes -->
To do it simply and quickly - down and dirty, put the code you want to run in a method in the code-behind. then simply call the method before the MainWindow() InitializeComponent(). This poses dangers, but most times it works because the components are loaded before window initiation/display.
(This is working code from one of my projects.)
Let's say you want to play a short wave file when the app fires up. It would look like this;
using ...
using System.Windows.Media;
namespace yourNamespace_Name
{
/// sumary >
/// Interaction logic for MainWindow.xaml
/// /sumary>
public partial class MainWindow : System.Windows.Window
{
public MainWindow()
{
/*call your pre-written method w/ all the code you wish to
* run on project load. It is wise to set the method access
* modifier to 'private' so as to minimize security risks.*/
playTada();
InitializeComponent();
}
private void playTada()
{
var player = new System.Media.SoundPlayer();
player.Stream = Properties.Resources.tada;
// add the waveFile to resources, the easiest way is to copy the file to
// the desktop, resize the IDE window so the file is visible, right
// click the Project in the solution explorer & select properties, click
// the resources tab, & drag and drop the wave file into the resources
// window. Then just reference it in the method.
// for example: "player.Stream = Properties.Resources.tada;"
player.Play();
//add garbage collection before initialization of main window
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
Hope this helps those that are searching. :-)
Loaded event is raised after project is build. To do stuff before, you can ovveride OnStartup method in App.xaml.cs.
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
//...
base.OnStartup(e);
}
}