How to handle a system.InvalidOperationException when converting from System.windows.FormsMessageBox to Xceed.Wpf.Toolkit.MessageBox - messagebox

I have a very bland messagebox asking my users a simple question (not yes or no). For quick development I used a simple System.Windows.Forms.MessageBox and worded the question ("If you want to choose 'A' click 'Yes' if you want to choose 'B' click 'No'"). Now I'm going back and improving the look and feel of my wpf application and I'm stuck trying to convert this MessageBox into something that looks good.
My preliminary search told me to use Xceed.Wpf.Toolkit.MessageBox to be able to create custom message box but I'm getting an exception when I'm trying to use it.
Old Code
DialogResult dialogResultForDataDisplay = System.Windows.Forms.MessageBox.Show("Yes: Display by properties \n \t Each row will contain data for a specific asset class in a specific submarket during a specific quarter. \n \n No: Display by quarters \n \t Each row will will show the change over time for a specific property of an asset class in a specific submarket.", "Data Grouping Format", MessageBoxButtons.YesNo);
New Code
Style style = new Style();
style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.YesButtonContentProperty, "By Property"));
style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.NoButtonContentProperty, "By Quarter"));
MessageBoxResult result = Xceed.Wpf.Toolkit.MessageBox.Show("How do you want your information displayed?", "My caption", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes, style);
Console.WriteLine(result);
The new code is generating this exception: System.InvalidOperationException: 'The calling thread must be STA, because many UI components require this.'
How would you go about handling this exception?

One solution I found now is rapping it in an invoke method. If someone has a better solution please post.
MessageBoxResult result = MessageBoxResult.None;
System.Windows.Application.Current.Dispatcher.Invoke((Action)delegate
{
Style style = new Style();
style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.YesButtonContentProperty, "Yes, FTW!"));
style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.NoButtonContentProperty, "Omg, no"));
result = Xceed.Wpf.Toolkit.MessageBox.Show("How do you want your information displayed?", "My caption", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes, style);
}
Console.WriteLine(result);

Related

Directline choice prompt not displaying correctly

Hi we have a chatbot which is developed using bot framework and integrated in Webchat. In this choice prompt display is not correct. At some time it will display as buttons sometimes not. What may be the issue?
This is by design defaulting to ListStyle.auto as can be seen in the ChoicePrompt class here. The ChoicePrompt class extends the Prompt class which, if no prompt style (inline, list, suggest action, hero card, or none) is supplied, then it defaults to calling ChoiceFactory.forChannel(). This method runs an algorithm that checks a variety of factors to determine the best style for the given channel.
The forChannel() method checks, among other things, the number of choices included and the length of each choice title. If the title's length is too long, limited to 20 characters (ref here), and the number of choices is over 3 (ref here), then default to a list.
This is what is happening to you. However, you can overwrite this by simply passing in the style property in the prompt, like so:
async choiceStep(stepContext) {
const choices = ['Hello', 'No soup for you!', 'Execute Order 66', 'You shall not pass!', 'Make it so, number 1', "You can't handle the truth!"]; // , `${ Number(66) }`];
return await stepContext.prompt(CHOICE_DIALOG_SUB_PROMPT, {
prompt: "Choose and option ,eh?",
choices: ChoiceFactory.toChoices(choices),
style: ListStyle.suggestedAction
});
}

I am having trouble with writing ScriptRunner Behaviours

I am trying to set two behaviors, but it is very hard because I do not have any coding background. The idea is that the ticket creation screen would hide/show fields depending on what the user chooses.
So the first behavior should be from a dropdown menu with 3 options (SAP, Jira, Other) and the dropdown menu's name is Affected Software. If the user chooses SAP, a textfield to appear which is called Transaction number. If they choose other, another textfield should appear called Please enter software name and otherwise, these should be hidden and not show any other fields.
Here is the code I tried to write:
import com.onresolve.jira.groovy.user.FormField
FormField dropDown = getFieldByName("Affected Software")
FormField other = getFieldByName("Transaction Number")
FormField other = getFieldByName("Please enter software name")
if (dropdown.getFormValue() == 'SAP') {
other.setHidden(false)
other.setFormValue("SAP chosen")
} if else (dropdown.getFormValue() == "Other")
other.setHidden(false)
other.setFormValue("Other chosen")
else {
other.setHidden(true)
}
The second behavior is a bit simpler. There is again a dropdown field called Is there a workaround with these options(yes, no, I don't know). If the user chooses yes, a field should show up called Explain the workaround. Otherwise nothing should change.
This is the code I tried to write for that one
import com.onresolve.jira.groovy.user.FormField
FormField dropDown = getFieldByName("Is there a workaround?")
FormField other = getFieldByName("Explain the workaround")
if (dropdown.getFormValue() == 'yes') {
other.setHidden(false)
other.setFormValue("yes chosen")
} else {
other.setHidden(true)
}
Could you please let me know what I am doing wrong? Thank you in advance!
I think you are looking for getValue() rather then getFormValue() as this will give you the ID of the underlying value, like an option ID.

Search Bar return Button

I have a searchBar in a tableview, searching for results in a .csv file (coredata). The list is huge so the user has to scroll up many times to reach the search bar after the first search OR select the "A" letter in the Indexbar. Is there a way to add a button in the NavigationBar to show the searchBar when the user wants to get back to the beginning of the list? Thanks in advance.
searchController = UISearchController(searchResultsController: nil)
tableView.tableHeaderView = searchController.searchBar
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionTitles[section]
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
//assume a single section after a search
return (searchController.active) ? 1 : sectionTitles.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.active {
return searchResults.count
} else {
// Return the number of rows in the section.
let wordKey = sectionTitles[section]
if let items = cockpitDict[wordKey] {
return items.count
}
return 0
}
}
I don't know how to send the user direct to a search bar, but there are always other ways to do things, what you can do is: Reload the storyboard and then it will show again the search bar in the initial states. Take a look on this interesting post: How do I perform an auto-segue in Xcode 6 using Swift? maybe you can go to another VC and return immediately with an simple animation so the user will not notice the tricker. :)
Yes, you can add a UIBarButtonItem to your navigation bar where the action you do will scroll the table back to the top.
Just replace the code from tableView.tableHeaderView = searchController.searchBar to navigationItem.titleView = searchController.searchBar which shows the searchBar on the NavigationBar.
But when you select the searchBar then it goes upward and might be not visible on the screen, so you can take the UISearchBar instead of UISearchController. For more information please look into these thread.
This is not exactly an answer to your question, but still a solution to your problem of quickly returning to the top of your table view. You could overwrite the table view's scrollsToTop: -property to return YES. By doing so, you will enable the user to jump to the top of the table by simply tapping the status bar. This is standard behavior in many stock apps, such as Contacts, Mail, Safari, and Photos.
Beware that only one scroll view / table view / collection view on the screen may return YES in order to achieve this behavior. In the case of multiple scroll views, you can alternatively implement the UIScrollViewDelegate -protocol's
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
callback and dynamically check, if the given scroll view should respond to the tap.
Although this is the Objective-C -way, I guess you should be able to transfer the concept over to Swift.
This approach has two advantages:
You will not clutter your navigation bar. Apples iOS Human Interface Guidelines explicitly suggest to
Avoid crowding a navigation bar with additional controls, even if it looks like there’s enough space. In general, a navigation bar should contain no more than the view’s current title, the back button, and one control that manages the view’s contents.
You will be consistent with the OS' standard behavior.

how to check nothing has changed in cucumber?

The business scenario I'm trying to test with cucumber/gherkin (specflow, actually) is that given a set of inputs on a web form, I make a request, and need to ensure that (under certain conditions), when the result is returned, a particular field hasn't changed (under other condition, it does). E.g.
Given I am on the data entry screen
When I select "do not update frobnicator"
And I submit the form
And the result is displayed
Then the frobnicator is not updated
How would I write the step "the frobnicator is not updated"?
One option is to have a step that runs before "I submit the form" that reads something like "I remember the value of the frobnicator", but that's a bit rubbish - it's a horrible leak of an implementation detail. It distracts from the test, and is not how the business would describe this. In fact, I have to explain such a line any time anyone sees it.
Does anyone have any ideas on how this could be implemented a bit nicer, ideally as written?
I disagree with the previous answer.
The gherkin text you felt like you wanted to write is probably right.
I'm going to modify it just a little to make it so that the When step is the specific action that is being tested.
Given I am on the data entry screen
And I have selected "do not update frobnicator"
When I submit the form
Then the frobnicator is not updated
How exactly you Assert the result will depend on how your program updates the frobnicator, and what options that gives you.. but to show it is possible, I'll assume you have decoupled your data access layer from your UI and are able to mock it - and therefore monitor updates.
The mock syntax I am using is from Moq.
...
private DataEntryScreen _testee;
[Given(#"I am on the data entry screen")]
public void SetUpDataEntryScreen()
{
var dataService = new Mock<IDataAccessLayer>();
var frobby = new Mock<IFrobnicator>();
dataService.Setup(x => x.SaveRecord(It.IsAny<IFrobnicator>())).Verifiable();
ScenarioContext.Current.Set(dataService, "mockDataService");
_testee = new DataEntryScreen(dataService.Object, frobby.Object);
}
The important thing to note here, is that the given step sets up the object we are testing with ALL the things it needs... We didn't need a separate clunky step to say "and i have a frobnicator that i'm going to memorise" - that would be bad for the stakeholders and bad for your code flexibility.
[Given(#"I have selected ""do not update frobnicator""")]
public void FrobnicatorUpdateIsSwitchedOff()
{
_testee.Settings.FrobnicatorUpdate = false;
}
[When(#"I submit the form")]
public void Submit()
{
_testee.Submit();
}
[Then(#"the frobnicator is not updated")]
public void CheckFrobnicatorUpdates()
{
var dataService = ScenarioContext.Current.Get<Mock<IDataAccessLayer>>("mockDataService");
dataService.Verify(x => x.SaveRecord(It.IsAny<IFrobnicator>()), Times.Never);
}
Adapt the principle of Arrange, Act, Assert depending on your circumstances.
Think about how you would test it manually:
Given I am on the data entry screen
And the blah is set to "foo"
When I set the blah to "bar"
And I select "do not update frobnicator"
And I submit the form
Then the blah should be "foo"

CKEditor dialogs: referencing input fields by ID

Each input field in the CKEditor dialogs are renamed with a unique number, but the number changes depending on what options are visible.
I need to reference 'txtUrl' which has an id something like #35_textInput.
So far I have discovered that something like this should work:
alert(CKEDITOR.instances.myElement.document.$.body.getId('txtUrl'));
But it doesn't. Please help.
#Rio, your solution was really close! This was the final solution:
var dialog = CKEDITOR.dialog.getCurrent();
dialog.setValueof('info','txtUrl',"http://google.com");
return false;
var dialog = this.getDialog();
var elem = dialog.getContentElement('info','txtUrl');
within an onchange part of an element I now use
dialog = this.getDialog();
alert(dialog.getContentElement('info', 'grootte').getInputElement().$.id);
and it gives 'cke_117_select' as a result. (It's a selectbox)
alert(dialog.getContentElement('info', 'txtUrl').getInputElement().$.id);
gives 'cke_107_textInput'.
I think this is what you (or other visitors to this page) are looking for.
SetValueOf still doesn't provide the id, which you may need if you want to do more than fill a text field with a certain text.

Resources