I want to be able to detect using events, when a Window (not necessarily the application I'm creating) changes its title.
My ideas (but none of them uses a specialized event):
Add an event to the mouse click and keyboard strokes, that way I can detect when the title will change, but it's not perfect, since the title may change a few seconds after the last click (e.g. loading a website)
Do some polling only on whitelisted applications
EDIT: I managed to put the EVENT_SYSTEM_CAPTURESTART hook, which captures clicks. It does work for changing tabs, but for loading new pages, it will not capture the change because pages usually take some time to load.
I'm doing this by using UIA (as suggested by Hans). I detect when a new window opens, get the UIA element, and subscribe to the property changed event handler for it for the NameProperty.
Automation.AddAutomationPropertyChangedEventHandler(
<your window AutomationElement>,
TreeScope.Element,
<your delegate>,
AutomationElement.NameProperty);
Related
I have written a custom OnScreen Keyboard as an UserControl to have a better control over what the user can type (Alphanumeric/Numpad/Navigation Keys - stuff like that) and to have a better control over the screen layout at design time.
The OSK works by manipulating the text- and selection-properties/functions of a textbox-control.
My main Problem is how to find the right TextBox to inject text into.
My first, naive approach was to register every TextBox I want to use with the OSK Control manually and use the GotFocus/LostFocus of those registered TextBoxes to determine the active control:
public void RegisterInput(TextBox text) {
if (!_listeners.ContainsKey(text)) {
_listeners.Add(text, modes);
text.GotFocus += Input_OnGotFocus;
text.LostFocus += Input_OnLostFocus;
}
}
private void Input_OnLostFocus(object sender, RoutedEventArgs routedEventArgs) {
if (_focused == sender) {
_focused = null;
IsEnabled = false;
UpdateKeyboardMode(); // << Updates Keyboard layout (Alphanumerical vs Numpad) based on focused control
}
}
private void Input_OnGotFocus(object sender, RoutedEventArgs routedEventArgs) {
_focused = (TextBox) sender;
IsEnabled = true;
UpdateKeyboardMode();
Bindings.Update();
}
I work with Focus here, because I need to determine which kind of keyboard (full-size alphanumerical vs. short numpad) to display for each TextBox. The _focused TextBox is then used to directly inject the pressed keys into it. In the constructor of my Page which also contains the OSK-control I would call RegisterInput() with a reference of each and every TextBox I defined on the page. This works just fine — if I have those references.
But now I am working with UserControls. That also removes the TextBoxes out of reach for direct referencing, but I could write some kind of VisualTree-Scan after InitializeComponent() to find all references and call RegisterInput() on each reference I found. If I only need to do this once, it isn't a problem (altough it is still ugly).
One step further - ListBoxes with dynamicly changing contents and DataTemplates. Now I'd need to rescan the whole VisualTree explicitly everytime something changes. But how to detect those changes?
The question is: Can I get an event as soon as $any element in my VisualTree gets/looses focus, without knowing all those elements beforehand (thus replacing RegisterInput() completely)? Or can I listen to changes to the VisualTree to rescan all controls and then call RegisterInput() manually for every TextBox I found?
The goal is to get a handler called everytime a GetFocus/LostFocus event on any TextBox/Control in the UI is raised so that I can update the keyboard to either display a full-sized alphanumerical keyboard (for default textboxes) or a shortened numpad (e.g. for textboxes bound to numerical backing fields).
Alternatively: Is there any other way to inject text and call UpdateKeyboardMode() to update the keyboard layout as soon as the selected textbox changes?
Other options I thought about include:
Build a custom control which derives from a TextBox and let it register itself to the OSK. I'll probably resort to this method, if I don't find any better way. But this will destroy support for 3rd party libraries in which my control is not present and thus does not use the "special magical textbox with osk support".
Don't use events at all. Get the currently focused TextBox with the FocusManager as soon as the user presses a key on my OSK and inject text into the focused instance. Problem with this approach is, that it completely destroys the capability to adapt the OSK to different input types (alphanumerical vs only Numpad), because I cannot determine the keyboard type I need before pressing a key.
Rescan the VisualTree with a timer. Won't do that, thats simply too much of a hack.
Use the OnScreen-Keyboard supplied by Win10 IoT. Two problems: It has no designtime support and is displayed above elements, even if the focused element is directly underneath the keyboard (acceptable if neccessary), but I don't know of a way to change the keyboard "layout" between a full-sized alphanumeric keyboard and a shortened Numpad which only contains numbers and some keys. Also it does not allow to use custom keys (e.g. arrow keys for navigation, custom return key handling).
After a discussion in the chat forum, the actual problem isn't to create a Custom OSK control and use that to interact with the TextBoxs but instead, it's "being bound to use custom control" wrapping a textbox everywhere a OSK needs to be shown.
The Solution would be to listen to the OS-OSK events and when they are triggered, pop up the Custom OSK this ways you won't have to wrap a Textbox in a user control and use that throughout your project.
Link to the Documentation: - respond to the presence of the touch keyboard
I'm writing a custom picker with the PickerFlyout class. By setting the ConfirmationButtonsVisible property to true, the flyout will show an application bar with an accept and a cancel button.
My problem is that the picker I am writing does not always have a valid value, and therefore I would like to disable the accept button when it does not make sense. Is there a way to do this in a Windows Phone 8.1 XAML app ("Store app")?
Other possible solutions:
An alternative solution would be to show my own app bar instead of the one given by ConfirmationButtonsVisible, which is possible by setting one in the Opening event. However, when this is done if the "overflow dots" of the application bar is clicked, the flyout will close. Apparently there is no way to prevent a flyout from closing.
If all else fails I will have to write a custom Popup, but I would rather not do this because the opening and closing animations used by PickerFlyout do not seem to be available as resources (internal to the class maybe?).
As long as there are items only in the PrimaryCommands section the flyout stays on screen when the overflow dots are tapped. Thus it is possible to temporarily replace the page's app bar with a new one for the duration of the flyout as long as no items in SecondaryCommands are needed. The accept button can be disabled in this new app bar.
For the last 2 month I've written application in C# in Visual Studio. Now i have to port that application to Linux by Monodevelop. Well, I already solved most of the porting errors, but there is one that i cant figure out. All double click and mouse double click events from Visual Studio stopped working - I even created small 1-form application that i ported to Mono with only form and one event (double click) - it also didnt work - so that means Monodevelop cant port double click events from Visual Studio ? I already checked WND_Proc function and Linux dont throw up any corresponding double-click event (it was 515 for in window and 3 hundred something on title bar...). Im already giving up and preparing for writing additional code to fix all double-click issue in my code but maybe someone has an answer.
Im using Ubuntu linux (if its neccesary i might tommorow check kernel version), MONO: 2.8.3, Visual Studio 2008 and project in .NET 3.5.
When implementing mouse clicks, there are two main differences between Windows and Gtk# that you should keep in mind:
Gtk# does not offer a 'double-click' signals ('Events' in Windows lingo), but only single 'click' signals. However Gdk library does implements both double-click and triple-click with its EventButton class!
Gtk# differentiates between Widgets (or 'Controls' in Windows lingo) and 'Containers' (there is no direct comparable in Windows). Most widgets placed on a Gtk# form will NOT receive mouse click events. In order to receive a mouse event you need to place the widget inside a specific container - like EventBox.
Here is how you do it Gtk#:
A. Add an EventBox containter to your form (in the example below: eventbox1). You can place it behind other Widgets or since it is not visible, unless you specifically select it to be (or change its background color). You can put a widget inside the EventBox, but you are limited to only one widget, that will also get the shape and size of the EventBox.
B. Add to this EventBox the signal 'ButtonPressEvent' out of the "Common Widget Signals" (in the example below: OnEventbox1ButtonPressEvent)
Every time a mouse button (left, middle or center or a combination) is clicked inside the EventBox, it will trigger this event and the function OnEventbox1ButtonPressEvent() will be called. If you need to identify the button that was clicked while handling this event, use the uint value in: args.Event.Button typically '1' will be the left mouse button, '2' the center button and '3' the right button ('2' might be also when both left and right buttons are clicked).
By the way, mouse motion events (without a button press) are not sent by default. So if you need to sense them you will need to add the PointMotionMask as well in the first like of the code example below.
Here is a code example of the ButtonPress Event Handler (the EventBox name is 'eventbox1') catching a double-click event using the EventButton class:
// The following line is may not be needed but is here to show how to do it
eventbox1.GdkWindow.Events = eventbox1.GdkWindow.Events | Gdk.EventMask.ButtonPressMask;
protected void OnEventbox1ButtonPressEvent (object o, ButtonPressEventArgs args)
{
if( ((Gdk.EventButton)args.Event).Type == Gdk.EventType.TwoButtonPress)
System.Media.SystemSounds.Beep.Play (); // Play a sound only if this is a double-click event
}
The order of the events received (in case of a double click) is:
Gdk.EventType.ButtonPress
Gdk.EventType.ButtonRelease
Gdk.EventType.ButtonPress
Gdk.EventType.TwoButtonPress
Gdk.EventType.ButtonRelease
Hope that helps!
GTK# treats double-click events differently than Windows Forms. You're going to have to write code to translate the events. If you're doing that, you may as well spend the time arguing against double-click as an idiom.
I am using the Business Silverlight application. I have incorporated some MVVM into this and were off an running with it. We are using some telerik controls, mostly the ribbon control and the docking. We register all the telerik ribbon controls in the about.xaml.cs file, the method is DisplayUI - its here where we register the docking control then we register the ribbon after this. What happens is that when you click the ABOUT link it shows our first tab with buttons(perfect). when you click the HOME link next to the ABOUT link, we go back to the home page..but when you click the ABOUT link again it registers the controls again so we end up with two tabs that are the same.
Is there a way to check to see if this about.xaml.cs file has already been initialized? Im guessing that is has a handle on the first call in memory as I am able to see the first tabs rendering..
Thanks
here is the about code
public About()
{
InitializeComponent();
DisplayUI();
this.Title = ApplicationStrings.AboutPageTitle;
}
that display UI does all the work in registering the dockpanel and the ribbons. We'd like to not have the DisplayUI() called if this has already been rendered once.
If you do it by event handler can you unsubscribe from the event at the end of the method? Without seeing some code it's hard to work out what to change.
It's not the nicest way of doing it, but if this code needs to run once and only once then you could have a static boolean variable on the class set to false and when you call DisplayUI you check the value of this. If it's false you set it to true and run the method, and if it's true you just return.
I want to implement different functionalities for single and double click on image.
I was earlier using Manipulationstarted event .What could be used now?
I am using help from click count
but (e.ClickCount) is not supported
You can do this with the gestures in the Silverlight for Windows Phone Toolkit
e.g.:
<Image Source="filename.png" >
<Controls:GestureService.GestureListener>
<Controls:GestureListener
Tap="GestureListener_Tap"
DoubleTap="GestureListener_DoubleTap" />
</Controls:GestureService.GestureListener>
</Image>
Beware that the tap event will always be called even when the double-tap event is also called. You could attempt to work round this by having a check in the tap event. (You'd need to have a short timer running on a different thread and if the double click isn't tirggered in this time then assume a double click.)
HOWEVER
From a usability point of view, you may make it easier on your users by having a tap event and a context (tap and hold) menu. This will make it much harder for the user to accidentally select the wrong option and it also gets rid of the problem above.
Having an object support both a tap (or click) and double tap event is not common because it's harder to discover or indicate to users and is easy to use the wrong action. Adding a context menu (right click menu on a PC) is the common convention for adding multiple options to users.
There is a ContextMenu also included in the Toolkit.
Shaireen,
Check out my simple blog article here: The simplest way to detect DoubleClick in Silverlight. That should give you the ability to detect both single Click's and DoubleClick's.
Good luck,
Jim McCurdy
You can use Tapped event for single click and DoubleTapped event for double click in windows phone 8.1
Why you don't have your own local counter variable.