How to get IsKeyDown method to work in C# - c#

I can’t figure out how get this method to work:
System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key)
The object browser says the following:
public static bool IsKeyDown(System.Windows.Input.Key key)
Member of System.Windows.Input.Keyboard
Summary:
Determines whether the specified key is pressed.
Parameters:
key: The specified key.
Return Values:
true if key is in the down state; otherwise, false.
Okay, so it’s a member of Keyboard, right? I used the following code:
Keyboard test = new Keyboard();
But when I type test and then the dot, IsKeyDown is not an option. The only options are from the Windows.Forms members. What am I missing here? Thanks.

Add PresentationCore.dll assembly as a reference.
Add WindowsBase.dll assembly as a reference.
Test code:
private void buttonMisc_Click(object sender, EventArgs e)
{
if (System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.LeftShift) == true)
MessageBox.Show("Got it!");
}

IsKeyDown is static, so you need to use it like
Keyboard.IsKeyDown()
Not with an instantiated object.
You also need to make sure you have the correct using statement at the top:
using System.Windows.Input;
EDIT
On further inspection, Keyboard is a static class... So you can't Keyboard test = new Keyboard();

Related

Partial Instantiation

This is more a question of terminology than how to do something.
I found a sort of 3rd state a property can be in. The first is a valid property. For example, bool is true or false. The second is null. The third I do not know what to call it. It is a property of an object that has been instantiated. This property kind of looks like it has not been instantiated. Not sure is that is the proper way to state it.
Example: Working with System.Diagnostics.Process to open a virtual keyboard, OSK. I need a routine to toggle the keyboard on and off. This works great.
using System.Diagnostics;
namespace Bsc
{
public static class OnScreenKeyboard
{
private static Process virtualKeyboard = new Process();
public static void ToggleHideShow()
{
try
{
if (virtualKeyboard.HasExited)
virtualKeyboard = Process.Start("osk.exe");
else
virtualKeyboard.Kill();
}
catch
{
virtualKeyboard = Process.Start("osk.exe");
}
}
}
}
Looking at the object virtualKeyboard in a watch window I can see how virtualKeyboard has been instantiated, but not completely. On the first pass virtualKeyboard.HasExited throws an exception. Watching the watch window, it also looks like it is not there. The line has a nice bright red dot in front of it with an X in it.
Name
Value
Type
HasExited
'virtualKeyboard.HasExited' threw an exception of type 'System.InvalidOperationException'
bool {System.InvalidOperationException}
Still on first pass the try/catch jumps to the Process.Start. After this executes the line looks like you would expect for an instantiated property.
Name
Value
Type
HasExited
false
bool
All calls after the first one HasExited works like you would expect and the method toggles the keyboard on and off.
I have not run into an object before that seemingly was only partially instantiated. What are the proper technical terms for this scenario? I have used the term ‘instantiated’, is that correct?
As per the documentation, the HasExited property throws an InvalidOperationException when there is no OS process associated with the Process instance.
Your property is initialized to a new instance of the Process class, which has not been started. Therefore, there is no OS process associated with that instance, and the HasExited property will throw an exception.
Remove the field initializer, and test for null in your method.
public static class OnScreenKeyboard
{
private static Process virtualKeyboard;
public static void ToggleHideShow()
{
try
{
if (virtualKeyboard == null || virtualKeyboard.HasExited)
virtualKeyboard = Process.Start("osk.exe");
else
virtualKeyboard.Kill();
}
catch
{
virtualKeyboard = Process.Start("osk.exe");
}
}
}
It is not possible for an object to be half-initialised based on the working of the language. If an object is not in a correct state, this is due to the working of the class/properties etc, and how the code has been written to initialise the object or not throw an exception when accessing the properties.
If the object does not always do what you expect then you have to check for the exception, do some defensive coding and handle the various scenarios in your own code.

Displaying<List> reports in a message box

Within my WinForm i have a method that checks the validation of various user controls and adds them to an errorList. When the user clicks the save button I want it to check the validation method and show the errors if any in a message box. The Validate method is in another form and class so i think that might be my problem.
private void Save_Click(object sender, EventArgs e)
{
var errorList = string.Join(Environment.NewLine, Validate.ToArray());
MessageBox.Show(errorSet);
}
Thank you for any help.
The error 'Form1.Validate(System.Collections.Generic.List<string>)' is a 'method', which is not valid in the given context means that you're using the method wrong.
var errorList = string.Join(Environment.NewLine, Validate.ToArray());
makes no sense. You're missing the parentheses:
var errorList = string.Join(Environment.NewLine, Validate().ToArray());
That's only one problem. The method has a parameter of type List<string>, but you don't pass an argument to the function.
Also, you said in a comment that the return value is of type bool, but it seems you expect it to return a collection of strings.
You have this issue because you are calling the validate method that is on another form without mentioning the instance of that form.
Lets say you have another class Class1.
//create instance of your class/form that has this method
OperationControl oc = new OperationControl ();
private void Save_Click(object sender, EventArgs e)
{
//call the method with form instance created above
var errorList = string.Join(Environment.NewLine, oc.Validate().ToArray());
MessageBox.Show(errorSet);
}
some time this error means you may have the same method with the same name in your program scope. Check if no other function named MessageBox exist in your program

How to solve case insensitive conflict name in COM while I using a case sensitive language

This question is an extension of this article.
In the same case, I created a instance of WMP ActiveX by its ProgID.
protected const string WMP_PROG_ID = "WMPlayer.OCX.7";
private dynamic _wmp;
protected virtual bool init(){
try{
_wmp = Activator.CreateInstance(Type.GetTypeFromProgID(WMP_PROG_ID));
}
catch{ return false; }
return connectEvent();
}
According the MSDN document, there are an Error event and an error property in WMPlayer object.
So, I try to attach events like this way.
protected bool connectEvent(){
try{
_wmp.PlayStateChange += new StateHandler(_wmp_PlayStateChange);
//_wmp.Error += new Action(_wmp_ErrorEvent);
}
catch { return false; }
return true;
}
protected void _wmp_PlayStateChange(WMPlayerState state){
//do something I like
}
protected void _wmp_ErrorEvent(){
//do some error handling
}
If I keep //_wmp.Error += new Action(_wmp_ErrorEvent) commented,
there's no compile error and PlayStateChange works pretty good.
However, if I remove the comment mark, there's a runtime exception.
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: can not apply operator "+=" between 'System.__ComObject' and 'System.Action'
It seems the two "error" are conflicted because COM is case insensitive. How can I solve it?
My goal is that attach to "Error" event without using AxWindowsMediaPlayer.
I ran in to a very similar problem as you but mine was with Size. The strongly typed ActiveX control redefined Size so I needed to cast it back to Control when the forms designer wanted to size the control on my form.
((Control)this.axLEAD1).Size = new System.Drawing.Size(298, 240);
If you can get a strongly typed class for the com object (by adding a reference or using tlbimp.exe) you may be able to cast to the strongly typed com object instead of __ComObject and have it use the correct method.

Use of 'this' in an event

I need to retrieve some property of an element that trigger the event in this context:
SoundEffect alarm;
public MainPage()
{
InitializeComponent();
Pad1.MouseLeftButtonUp += new MouseButtonEventHandler(makeasound);
Pad2.MouseLeftButtonUp += new MouseButtonEventHandler(makeasound);
Pad3.MouseLeftButtonUp += new MouseButtonEventHandler(makeasound);
}
Pad1,2 and 3 are the names of some Ellipse I have in my xaml. Now if I try to do this in the code executed by the event ( declared immediately after the sample code above):
private void makeasound(object sender, MouseButtonEventArgs e)
{
string text = this.Name;
textBlock1.Text = text;
}
The Text Block becomes empty, so I guess the Name of the triggering element never gets there.
Now, things get more messy if I'm trying to retrieve a custom property of the "pads" called "Son", declared with the dependency method , which is a string, like this:
private void makeasound(object sender, MouseButtonEventArgs e)
{
string text = this.Son;
textBlock1.Text = text;
}
VS reports error:
'PhoneApplication.MainPage' does not contain a definition for 'Son' and no extension method 'Son' accepting a first argument of type 'PhoneApplication.MainPage' could be found (are you missing a using directive or an assembly reference?)
Where Phoneapplication is the name of the app and the main namespace of the code behind.
As if it weren't simple enough, what I'm tryin to do is this:
The custom property is actually an INT. I know I declared the dependency right since VS let me compile. Each Pad has this custom property storing an int, and I need to retrieve it to access an array element. The function triggered is this:
private void makeasound(object sender, MouseButtonEventArgs e)
{
int x = this.Son;
var sons = new[] { "sons/firstsound.wav", "sons/secondsound.wav", "sons/thirdsound.wav" };
string target = sons[x];
StreamResourceInfo info = Application.GetResourceStream(
new Uri(target, UriKind.Relative));
alarm = SoundEffect.FromStream(info.Stream);
Microsoft.Xna.Framework.FrameworkDispatcher.Update();
alarm.Play();
}
So, I declare an array storing URI's for sounds that I'd like to play("son" means sound in french, I'm from Belgium). I then use the INT associated with the triggering element to access the URI of a sound, then I play this sound.
The reason I do this is because I'd like to let the user change the INT value for each pad and therefore choose what sound each pad plays. The fact that I seem to have no choice but to declare this array each time the function is called (otherwise it's not in context) is not very elegant but I guess I can live with that ( array will have 50-60 elements in it)
So, for those who read this far, my problem is to use a property of the triggering event, which seems to be harder when it's a custom property. I put the rest of the logic in case someone had advices.
I thank anyone who read this message and who could maybe help me sorting this out. I read online documentation and I have two good c# books, but I havent found a solution for me.
Have a nice day.
EDIT: Some others are willing to help so here is the declaration of the dependency property(Sorry Daniel, hadn't seen you commented my original post)
namespace MyNamespace
{
public static class MyClass
{
public static readonly DependencyProperty SonProperty = DependencyProperty.RegisterAttached("Son",
typeof(string), typeof(MyClass), new PropertyMetadata(null));
public static string GetSon(UIElement element)
{
if (element == null)
throw new ArgumentNullException("element");
return (string)element.GetValue(SonProperty);
}
public static void SetSon(UIElement element, string value)
{
if (element == null)
throw new ArgumentNullException("element");
element.SetValue(SonProperty, value);
}
}
Mynamespace is nested inside the main namespace.
this refers to the current instance of MainPage. Not to the pad that was clicked. That's the sender:
var pad = (Pad)sender;
var text = pad.Name;
textBlock1.Text = text;
Son is an attached property, not a normal one. You can get its value like this:
var pad = (Pad)sender;
var son = MyClass.GetSon(pad);
Please note that you have declared it as a string. Seeing how you want to use it, it seems to make more sense to declare it as an int.
this refers to the instance of the type in which the method is defined in, in this case, MainPage. If you want to get the instance of the type that triggered the event, that's what's in the sender parameter:
private void makeasound(object sender, MouseButtonEventArgs e)
{
textBlock1.Text = ((Pad)sender).Name;
}

Attaching method to execute for an Event

I got an event from special API I'm working with, the event I'm working with is defined as
public event EventHandler<QuoteEventArgs> OnQuote
public class QuoteEventArgs : EventArgs
so what I'm trying to do is attach a method to run when I got a new Quote listening to this event.
so what I do is:
myInstance.OnQuote += new EventHandler<QuoteEventArgs>(doThis);
And the method is defined as:
public void doThis(object sender, QuoteEventArgs e){
//code here..
}
The error I get is:
Cannot implicity convert type 'System.EventHandler<MT4API.QuoteEventArgs>' to 'System.EventHandler'
but I don't seem to have a special eventHandler on the API either, so not quite sure how to make that work.
From the comment discussion, it appears that you are using a version of the library in which the event does not have a generic type, i.e. the signature is
public event EventHandler OnQuote;
This means you will also have to consume it in a non-generic way:-
myInstance.OnQuote += new EventHandler(doThis);
public void doThis(object sender, EventArgs e){
var myArgs = (QuoteEventArgs)e;
...
}
My guess is that there are two classes with the name QuoteEventArgs, perhaps one from a referenced DLL and one from a generated proxy. Ensure that if you've got usings that the usings are correct.

Categories

Resources