I am making a dialog with a command. This command must close the dialog and go back to the previous form, but it is not working as expected. When I press the command, it closes the dialog but the form do not go back.
I am using the resource editor. State machine controls the app´s navigation.
The code inside the command´s logic is:
dialog.dispose();
StateMachine.back();
Is dispose() the method that I must use to close my dialog?
Thanks for reading.
As Nirmal said disposing the dialog goes to the previous form so while your call to "back()" works as expected your call to dispose() breaks that logic.
You can override the postShow method for the form you are showing and detect the case of leaving the dialog (just turn on a flag when you need to go back) and call the back method when the form is shown in that condition.
dont call StateMachine.back() just use dialog.dispose();
There is another solution : try to use the protected void onShowCompleted() method that you must implement in your Form. And declare a boolean variable in your Form ( for example private boolean isDialogShown; ), then in the constructor of your Form set that boolean variable to false, and just before the code of opening the Dialog set its value to true. Then in the code of the protected void onShowCompleted() test if it is true , and if it is true then set it to false and perform the back action : backForm.showBack();
Related
I have a dialog that I would like to stay open except if the [x] or exit buttons are clicked. Dialogs seem to always close if you hit escape or if you hit enter when most objects are selected (e.g. string boxes), whether you use pose() or display(). Is there a way to prevent this?
Some public examples of when this occurs are DM Mitchell's "Example: Thread and Dialog Interaction" and "Example: Single Button Dialog" but it seems to apply to any dialog.
The exception seems to be a docked palette, but this functionality seems to be rather limited in GMS2.3/GMS3.
Example code to test:
class myUItest:UIframe
{
object Init( object self )
{
TagGroup dlgTGitems
TagGroup dlgTG = DLGCreateDialog("Modal",dlgTGitems)
TagGroup dlgField = DLGCreateIntegerField(12,20)
dlgTGitems.DLGAddElement(dlgField)
return self.super.init(dlgTG)
}
}
{
object DLG = ALLOC(myUItest).Init()
DLG.Pose()
DLG.display("Modeless")
}
There seems to be no way to prevent termination of modal dialogs (those presented via the Pose method of UIFrame) via the keystrokes you mention. However, would a modeless dialog work for your application? Such a dialog is created by invoking the Display method on your UIFrame object and it is not closed via esc or enter.
This issue is in the same application as my last question.
I'm experiencing some "odd" behavior, and I don't know if it's functioning as designed or if there's something wrong. In the 3rd party application that I'm "injecting" data into I experience different behavior when I manually edit a record vs. when my automated application edits a record.
If I run the 3rd party application and manually edit a record, the 'Save' and 'Undo' buttons in the toolbar become enabled once I begin typing in a field.
If I run the 3rd party application, then run my automated application to edit a record, my application sets focus to the first field on the form, then "injects" the data into the fields (it actually looks like someone is typing it in very fast) but the 'Save' and 'Undo' buttons stay disabled the whole time. I try to invoke the 'Save' button when I reach the bottom of the form, but I receive an error:
"An unhandled exception of type 'System.Windows.Automation.ElementNotEnabledException' occurred in UIAutomationClient.dll
Additional information: The operation is not allowed on a nonenabled element."
I used this code example on MSDN to insert text in the textboxes of the 3rd party application.
if (!element.TryGetCurrentPattern(
ValuePattern.Pattern, out valuePattern))
{
// Set focus for input functionality and begin.
element.SetFocus();
// Pause before sending keyboard input.
Thread.Sleep(100);
// Delete existing content in the control and insert new content.
SendKeys.SendWait("^{HOME}"); // Move to start of control
SendKeys.SendWait("^+{END}"); // Select everything
SendKeys.SendWait("{DEL}"); // Delete selection
SendKeys.SendWait(value);
}
// Control supports the ValuePattern pattern so we can
// use the SetValue method to insert content.
else
{
// Set focus for input functionality and begin.
element.SetFocus();
((ValuePattern)valuePattern).SetValue(value);
}
Perhaps I'm not searching the correct keywords, but Google has not been much help to me, and I only found one SO post that seemed related. If anyone can shed some light on this I'd really appreciate it.
TIA
UPDATES:
Re: why don't I check if button is enabled...
I don't know how to accomplish that, I was trying to do that earlier today. I have an AutomationElement that references the 'Save' button, but the AutomationElement doesn't have an Enabled property.
AutomationElement toolbar = _mainWindow.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "59392"));
AutomationElement saveButton = toolbar.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Commit Changes (CTRL S)"));
I tried to cast the AutomationElement as Button to check the Enabled property but I receive a build error "Cannot convert type 'System.Windows.Automation.AutomationElement' to 'System.Windows.Forms.Button'"
if (!((Button)saveButton).Enabled)
((Button)saveButton).Enabled = true;
...ok, more searching lead to this: UIAutomation Button Style Enabled
so now I can check if it is enabled, but I haven't figured out how to enable it yet.
2014.10.02 - I think it's not possible to enable a disabled button via UIAutomation. So I will modify my question a bit. If I manually click on an input field and begin typing the 'Save' button becomes enabled. If I use UIAutomation to modify the record the 'Save' button does not become enabled. So, how can I use UIAutomation to get the window into the same state that it's in when I manually edit the record?
You could try using the win32 api to send messages to the button directly. You can get all the handles you need from uiautomation just use the post message function like this.
public TestSetup AutomationLibrary;
[DllImport("User32.dll")] //http://msdn.microsoft.com/en-us/library/windows/desktop/ms644944(v=vs.85).aspx
public static extern int PostMessage(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam);
public int WM_ENABLE = 0x0A;
public int WM_COMMAND = 0x111;
public MainWindow()
{
InitializeComponent();
AutomationLibrary = new TestSetup();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
AutomationElement aeDesktop = AutomationLibrary.GetDesktop();
AutomationElement aeForm1 = AutomationLibrary.GetAutomationElement("Form1", aeDesktop);
AutomationElement aeDisabledButton = AutomationLibrary.GetAutomationElement("DISABLED", aeForm1);
IntPtr windowIntPtr = new IntPtr(aeForm1.Current.NativeWindowHandle);
IntPtr controlIntPtr = new IntPtr(aeDisabledButton.Current.NativeWindowHandle);
PostMessage(windowIntPtr, WM_COMMAND, (IntPtr)WM_ENABLE, controlIntPtr);
}
The TestSetup is my own home brewed automationlibrary but basically I am just getting automation elements then using the PostMessage function from User32.dll to enable the button. although it doesnt seem to actually enable the button, it does have the unintend consequence of clicking the button.
I used this article as reference for the postmessage function http://www.codeproject.com/Articles/487938/Re-Active-Disabled-Controls
Hope this helps
I have a User Control in VB.NET (VS 2010) inherited from a picturebox. I also have a class that holds 40 or so properties for the control. I also have a form with a property grid that is used as an editor. The editor form opens when clicking the "Custom" property of the control in the IDE. On the form are an OK and Cancel button which either saves or discards changes.
All of this works fine, but I need to have my control "refresh" when a property changes in the grid. The property grid has an event for this, but I don't know how to call or invoke my sub in the control to essentially repaint the control. If I call the sub directly nothing refreshes on the control until after I close the editor form (dialog). Is there a way to have the control repaint/redraw with the editor dialog still open?
Thanks,
EluZioN
Try using Context.Instance which is passed when your UI_Editor is invoked. In the GetEditStyle override, a Context object is passed. This holds a reference to the calling UserControl.
I do something like this (CUSTOM UI_TYPE_EDITOR):
Dim ContextOBJ as MyUserControl
Public Overrides Function GetEditStyle(ByVal context As System.ComponentModel.ITypeDescriptorContext)......
contextOBJ = CType(context.Instance, MyUserControl)
In the GetEditValue override, you can call ContextOBJ.Refresh and your UserControl should immediately reflect any changes. It works for me.
I just want to get access to an object in the modal dialog. The following example will explain exactly what I'm trying to do:
(This code is not working)
CAddDlg dlg;
CString S;
dlg.DoModal();
dlg.GetDlgItem(IDC_NAME)->GetWindowTextW(S);
MessageBox(S);
But an assert will fail and I can't get the text of the Edit control.
What should I do?
You can't access the controls of modal dialogs from outside. Even if you could, it's not a good idea. The caller of the dialog should not know how the data is represented in the dialog. What is now an edit control could be a listbox in the future.
The way to go is declare getter functions which you call after DoModal() (if it returned IDOK) and get the values there.
Check Can I return a custom value from a dialog box's DoModal function? for some examples
I want to override Dialog so that it disposes itself the very moment it shows.
though it is a strange question, but you can override onShow() or onShowCompleted() and call dispose() inside one of them to close the dialog immediately.