Modeless dialog created by modal dialog in Compact Framework - compact-framework

I am working on a Compact Framework application. This particular hardware implementation has a touchscreen, but its Soft Input Panel has buttons that are simply too small to be useful. There are more than one form where typed input is required, so I created a form with buttons laid out like a keypad. The forms that use this "keypad" form are modal dialogs. When a dialog requiring this "keypad" loads, I load the "keypad" form as modeless:
private void CardInputForm_Load(object sender, EventArgs e)
{
...
keypadForm = new KeypadForm();
keypadForm.Owner = this;
keypadForm.SetCallback(keyHandler);
keypadForm.Show();
}
The SetCallback method tells the "keypad" form where to send the keystrokes (as a Delegate).
The problem I'm having is that the modeless "keypad" form does not take input. It is displayed as I expect, but I get a beep when I press any of its buttons, and its caption is grayed-out. It seems like the modal dialog is blocking it.
I've read other posts on this forum that says modal dialogs can create & use modeless dialogs. Can anyone shed light on this situation? Is there a problem with my implementation?

I found the answer: Set the keypad form's Parent property, not its Owner property, to the form instance wanting the keystrokes. The keypad dialog's title bar stays grayed out, but the form is active.
private void CardInputForm_Load(object sender, EventArgs e)
{
// (do other work)
keypadForm = new KeypadForm();
keypadForm.Parent = this;
keypadForm.Top = 190; // set as appropriate
keypadForm.Show();
}
Be sure to clean up when done with the parent form. This can be in the parent's Closing or Closed events.
private void CardInputForm_Closing(object sender, CancelEventArgs e)
{
// (do other work)
keypadForm.Close();
keypadForm.Dispose();
}
There are two panels on the keypad form, one with numerals and one with letters and punctuation that I want. There is also an area not on a panel that is common to both, containing buttons for clear, backspace, enter/OK, and cancel. Each panel has a button to hide itself and unhide its counterpart ('ABC', '123', for example). I have all the buttons for input on the keypadForm fire a common event. All it does is send the button instance to the parent. The parent is responsible for determining what action or keystroke is desired. In my case I named the buttons "btnA", "btnB", "btn0", "btn1", "btnCancel", etc. For keystrokes, the parent form takes the last character of the name to determine what key is desired. This is a bit messy but it works. Any form wishing to use the keypad form inherits from a base class, defining a method for callback.
public partial class TimeClockBase : Form
{
public TimeClockBase()
{
InitializeComponent();
}
// (other implementation-specific base class functionality)
public virtual void KeyCallback(Button button)
{
}
}
The click event on the keypad form looks like this.
private void btnKey_Click(object sender, EventArgs e)
{
// play click sound if supported
(Parent as TimeClockBase).KeyCallback(sender as Button);
}
The method in the parent form looks like this.
public override void KeyCallback(Button button)
{
switch (button.Name)
{
case "btnCancel":
// setting result will cause form to close
DialogResult = DialogResult.Cancel;
break;
case "btnClear":
txtCardID.Text = string.Empty;
break;
// (handle other cases)
}
}

Related

How to close ComboBox list items when moving application window of my WinRT/C++ UWP application?

I have a pair of ComboBox controls having IsEditable() true as well as false.
When I am scrolling through my application or moving my application window (by clicking on the title bar) with list popup open, I would like to close the ComboBox list popup as otherwise there would be a weird delay in aligning the list correctly below the control.
Is this possible in UWP with WinRT/C++? If so, kindly suggest how to.
I did an investigation to find if any events are there to handle in such a scenario when ComboBox control is essentially displaced from initial position while moving the app window/scrolling the app, but couldn't find any help.
Edit: Adding ComboBox image from XAML Controls Gallery to demonstrate the behaviour. In case if IsEditable set as true, when popup is opened and application is scrolled then popup goes outside the window. Instead I would like to dismiss the popup itself. However, if IsEditable is set as false then we cannot scroll until the popup is dismissed.
Update: The code I tested for PointerWheelChanged
void CBFile2022X::OnPointerWheelChangedHandler( Windows::Foundation::IInspectable const& sender,
Windows::UI::Xaml::Input::PointerRoutedEventArgs const& eventargs )
{
OutputDebugString( L"PointerWheelChanged" );
if( ComboBox != nullptr )
{
ComboBox.IsEnabled( false );
ComboBox.IsEnabled( true );
}
}
I have to say that currently there is no event to detect if the application window is moved or changed its location.
Update:
You could handle the UIElement.PointerWheelChanged Event which will be fired when users scroll the mouse wheel. You could set the IsEnabled property of the ComboBox to false first and then set it to true, this will make the ComboBox lose its focus. Like:
private void Mypanel_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
FontsCombo.IsEnabled = false;
FontsCombo.IsEnabled = true;
}
Update2:
If you are using a ScrollViewer you could try to handle the ScrollViewer.ViewChanging Event.
private void ScrollViewer_ViewChanging(object sender, ScrollViewerViewChangingEventArgs e)
{
FontsCombo.IsEnabled = false;
FontsCombo.IsEnabled = true;
}

Libgdx Dialog buttons cannot be clicked

I have trouble properly implementing a dialog. It does not recognize button clicks - even the button down animation does not happen. However, it does recognize key presses (e.g. enter or esc in my case). Dialog does appear to be on top of the stage objects, so I'm confused why it isn't registering my clicks.
I have an InputMultiplexer with processors InputHandler class (implements InputProcessor) and stage, in that order:
InputMultiplexer im = new InputMultiplexer();
im.addProcessor(new InputHandler(stage));
im.addProcessor(stage);//trying to make dialog work by doing this
Gdx.input.setInputProcessor(im);
Here's my showDialog method defined in stage:
public void showDialog() {
Dialog dialog = new Dialog("Quit?", skin) {
#Override
protected void result(Object object) {
boolean exit = (Boolean) object;
if (exit) {
Gdx.app.exit();
} else {
remove();
}
}
};
dialog.button("Yes", true);
dialog.button("No", false);
dialog.key(Input.Keys.ENTER, true);
dialog.key(Input.Keys.ESCAPE, false);
dialog.show(this);
}
The showDialog() method is called from InputHandler when it recognizes that the game is over (I have it set so that the game state is checked and updated on touch up, since it's a touch based game). My understanding is that since the multiplexer receives false return from the InputHandler methods when the game is over, it then goes to the stage for input, which seems to be working only when I use key presses on the dialog, i.e. enter quits the game, esc removes the dialog, but clicking the buttons do nothing.
Here is my Screen's render function in case it's relevant:
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.graphics.getGL20().glEnable(GL20.GL_BLEND);
Gdx.graphics.getGL20().glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT | (Gdx.graphics.getBufferFormat().coverageSampling?GL20.GL_COVERAGE_BUFFER_BIT_NV:0));
stage.act();
stage.getCamera().update();
stage.draw();
}

How to make a default button in UWP app using XAML?

I'm trying to declare a button as default in UWP app but receive an error:
The property 'IsDefault' was not found in type 'Button'
How can I make a default button in UWP app?
I down know what IsDefault is in WPF but to get if a button is pressed in UWP you can use CoreWindow.GetForCurrentThread().KeyDown. Create a Method that will be called from when the button is pressed or VirtualKey.Enter is clicked.
public MainPage()
{
this.InitializeComponent();
CoreWindow.GetForCurrentThread().KeyDown += MainPage_KeyDown; ;
}
private void MainPage_KeyDown(CoreWindow sender, KeyEventArgs args)
{
switch (args.VirtualKey)
{
case Windows.System.VirtualKey.Enter:
// handler for enter key
break;
default:
break;
}
}
You can use key down event which you can place on any textbox for example if you are making a login page then probably there will be 2 textboxes for username and password then just add key down event handler to textbox as it will be the last mandatory field like this:
<PasswordBox KeyDown="PasswordKeyDown"/>
then you can handle this event as:
using System.Windows.Input;
private void PasswordKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
Login();
}
Hope it will help you :)
There is not easy or clean way to solve your problem because IsDefault is not available for uwp apps.
if you are using MVVM or you want to reuse your code I recommend you to use Behaviors and follow the examples that the other guys posted.
I need a Button which user can invoke by pressing the ENTER key.
In an UWP app, by default a Button can be invoked by pressing the Enter key. So I guess what you want is setting the focus on this Button when there are some other UIElements in your page.
You can refer to Keyboard navigation among UI elements,
By default, the tab order of controls is the same as the order in which they are added to a design surface, listed in XAML, or programmatically added to a container.
To focus on the Button which is not the first element, you can just give the TabIndex="1" property to your Button, this property can make your Button get focus whenever the page is loaded, but if you change the focus on other controls in this page, you will need to reselect this button by mouse clicking, touching or TAB key.

ToolStripButton = "Pressed"

I got a toolstripbutton, and when I click it, I want to make it stay "pressed" or "selected". Like a switch. And when I click another, make the pressed one "unpressed" again. Any ideas?
I think you want to use the CheckOnClick property. Set it to true, and the button should behave as you describe. In order to get (or set) the current state, use the Checked property.
Here is a full working sample:
public partial class Form1 : Form
{
private readonly IEnumerable<ToolStripButton> mutuallyExclusiveButtons;
public Form1()
{
InitializeComponent();
mutuallyExclusiveButtons = new[] { firstButton, secondButton };
}
private void ToolStripButton_Click(object sender, EventArgs e)
{
ToolStripButton button = sender as ToolStripButton;
if (button != null && button.Checked &&
mutuallyExclusiveButtons.Contains(button))
{
foreach (ToolStripButton item in mutuallyExclusiveButtons)
{
if (item != button) item.Checked = !button.Checked;
}
}
}
}
firstButton and secondButton are ToolStripButtons, both have CheckOnClick set to true, and their Clicked events hooked up to ToolStripButton_Click. This works also if there are more than two buttons in the group of buttons in which only one should be checked, just add any needed additional buttons to the mutuallyExclusiveButtons sequence.
As ChrisF said, what you are looking for is the "Checked" property. (The "CheckOnClick" property is actually not what you want, since you want a sort of mutually exclusive toggle between two ToolStripButtons.)
What you will need is to put code (into the click event of each button) that will set the Checked property of that button to True and the Checked property of the other button to False.
Actually, you can use CheckOnClick and then add code only to set the other button to False.
(Hmmm... I wonder when the Checked becomes set to True; can you capture the MouseUp etc. event of BOTH buttons into one handler, and uncheck BOTH buttons, and then CheckOnClick will check the appropriate one later? Just some geek stuff to complicate things unnecessarily in the name of simplifying things)
Maintain a flag as to what the status of a button is (pressed or normal). For each button press, call a method that refreshes the toolbar buttons to the correct state (either stay pressed or go back to normal).

SCSF: display view from another view against button click

i am facing one problem in SCSF.
I have two workspaces
MdiWorkspace
DeckWorkspace
i have two views in a module
Viewer (display in mdiworkspace)
Property Viewer (in deckworkspace)
in Viewer i have a button in toolbar whose purpose is to display PropertyViewer (another View).
how can i display this PropertyViewer in deckworkspace agaist button click event.
NOTE: i am not using Command[CommandName].AddInvoker(control, "click:) and CommandHandler
I'm going to assume your toolbar sits in a SmartPart that implements the MVP pattern. Have the button click event handler in the SmartPart fire an event that its presenter will handle. Your presenter code would look like this:
// Presenter code
protected override void OnViewSet()
{
this.View.ToolbarButtonClick += View_ToolbarButtonClick;
}
public void View_ToolbarButtonClick(object sender, EventArgs e)
{
// remove the handler so the property viewer
// will only be added the first time
this.View.OnToolbarButtonClick -= View_ToolbarButtonClick;
var propertyView = new PropertyViewer();
this.WorkItem.Workspaces[WorkspaceNames.MyDeckWorkspace].Show(propertyView);
}