How to get the user's new page selection in a Notebook control under Windows? - wxwidgets

In my app, when a user has made changes to the data on one page of my notebook control, I want to prompt them to save or discard their changes when they switch to a different page. I have bound the EVT_BOOKCTRL_PAGE_CHANGING event for this, and have created a handler method.
However, I can't tell what page the user is switching to. According to the wxBookCtrlEvent docs,
under Windows, GetSelection() will return the same value as GetOldSelection() when called from the EVT_BOOKCTRL_PAGE_CHANGING handler and not the page which is going to be selected.
Is there a workaround?

I guess as a workaround, you could use a mouse handler checking for when the left button is clicked. In a handler for that event you could do a hit test to see where the click was made and store the value of the tab that was clicked. Something like this:
void MyFrame::OnLeftDown( wxMouseEvent& event )
{
long flags;
int ht = m_notebook1->HitTest( wxPoint(event.GetX(),event.GetY()), &flags);
if( (flags & wxBK_HITTEST_NOWHERE) == 0 )
{
//store the value of ht somewhere
}
event.Skip();
}
void MyFrame::OnNotebookPageChanging( wxNotebookEvent& event )
{
//use the stored value of ht here
}

under Windows, GetSelection() will return the same value as
GetOldSelection() when called from the EVT_BOOKCTRL_PAGE_CHANGING
handler and not the page which is going to be selected.
So, call GetSelection from EVT_BOOKCTRL_PAGE_CHANGED to get the new page.

No, there is no workaround (if there were a reliable way to do it, wxWidgets would have been already doing it), the underlying native control simply doesn't provide this information.
You can either ask whatever you need to ask the user about in any case, independently of the page they're switching to, or ask them after they will have already switched -- which is, of course, going to look weird if you then decide to switch back.
If you really, really need this functionality, you might use non-native wxAuiNotebook instead.

Related

Best way to run an action until expected condition is met in Nightwatch.js?

I am automating a portion of a website that kicks off a job when you click a button. The status of the job is reported on the page in another field, but it isn't automatically pushed. The end user needs to click a Refresh button inside the page to see the latest status.
Something like this
browser.expect.element('#status').text.to.equal('Done').before(10000);
would work if the data was pushed without using interaction, but since I have to manually click another button to get the latest status that wouldn't work.
Is there a built in method to do something every [interval here] until [condition true] or [timeout reached] in Nightwatch? I don't want to use a hard pause since the job could take more or less time depending how the server is feeling.
By another field do you mean an iFrame, svg or perhaps another tab/window?
You don't need manually, there is an option to switch to a different window with the following:
Window Handles + SwitchTo:
command(windowNum){
const result = browser.windowHandles();
let handle = result.value[windowNum];
browser.switchWindow(handle);
}
Refresh a page
browser.refresh();
I don't believe there is a built in method in Nightwatch but I'm sure you can use a for loop and an if statement

How do I add/remove density colors on the Windows Universal App CalendarView control after loading?

CalendarViewDayItemChanging seems to be the way to add 'density colors' (coloured bars in a DayItem box) to a Windows Universal App CalendarView.
However CalendarViewDayItemChanging is only fired when the DayItem box is loaded i.e. on initial loading and possibly when navigating to a far enough date and back again such that the virtualisation re-loads the DayItem.
However when I create an appointment on the selected date I need to add a density color bar immediately, similarly if I remove an appointment, I need to remove that bar.
How do I get the control to reload or re-render that particular DayItem?
Notes:
There is only the SelectedDates available as a property
There is no obvious way to ge the DayItem collection
Setting the Visibility to Collapsed then Visible instantaneously does not trigger a reload.
There was a similar issue on the MSDN blogs here: https://social.msdn.microsoft.com/Forums/en-US/54c81ada-4147-474b-8425-524ec69bc749/uwp-calendarview?forum=wpdevelop
I think your best bet currently is to have your Appointment creation on a separate page and store a List of Appointments locally or in a db. That way when you navigate back to the Page with your calendar view you can reload the Calendar using the updated Appointment list.
I used the MyCalendarView.UpdateLayout method to force the control to hit the CalendarViewDayItemChanging event again.
I called the method from the DataContextChanged event on my UserControl. This way anytime I change the DataContext the density colors get updated. This is sufficient for my needs. It sounds like you want to do it on a different event.
private void UserControl_DataContextChanged(Windows.UI.Xaml.FrameworkElement sender, Windows.UI.Xaml.DataContextChangedEventArgs args)
{
if (this.DataContext is ObservableCollection<Event>)
{
eventCalendar.UpdateLayout();
}
}

BlackBerry 10 Cascades app stuck affecting property

I have an issue with a list/detail pattern. I have an Article class, inheriting from QObject, defining some properties (title, updated and content being the ones that matters for now). To populate my (QML) ListView, I have a C++ GroupDataModel, filled with some Article*. Here's my list's onTriggered:
onTriggered: {
if (indexPath.length > 1) {
currentArticle = dataModel.data(indexPath);
var page = articlePageDefinition.createObject();
nav.push(page)
}
}
As you can guess, the articlePageDefinition defines a page using the upper currentArticle property.
Now, when I display the articlePage once, it's working fine. I can go back, click on the same list item, display the same Article details, works great. But when I pick a second article, the app kind of freezes. I can go back in my navigation pane, but I can't click on list items anymore. I tried to add some logs, the onTriggered is stuck on currentArticle = dataModel.data(indexPath);. At this point, I can log every property of dataModel.data(indexPath) without any issue. I tried to not create/push the page, simply affect currentArticle and display some of its properties, it's working fine too. I really don't understand what I am doing wrong here, any help appreciated.
In case you need to see more code, everything is here: https://github.com/Kernald/tt-rss-bb10/tree/e29e3b616aa179dd42f66804ecc20a6a45b6bb22
Here what can cause the problem your are having:
You create the articlePage and bind it's data to the "currentArticle" global variable
When you go back the articlePage is not deleted.
You open an other instance of this same articlePage. The last one still bind its data to the same currentArticle instance.
When you go back and click another item: the previous articlePage still exists in memory. It binds to "currentArticle". The problem is, it's not the data of "currentArticle" that has changed but the object referenced by "currentArticle". The Qml binder just fails then.
I had a similar behavior of my app, but I did not inspect your github code if the reason can be the same. I think you can verify that more quickly than me.
When removing and adding a list item with the same index, the code gets stucked. I removed an entry on user action and added a new one at that place, and it got stuck. This is a known issue to BB10, I found here: https://developer.blackberry.com/cascades/download/releasenotes/#known

Clearing ISupportIncrementalLoading

I have created a search page in a Windows 8 Style App. I have implemented ISupportIncrementalLoading and when the user scrolls the paging works great.
The problem that I'm having is when a user does a second search. I apparently don't know how to get the LoadMoreItemsAsync to fire again. I've tried the following:
1) Clear the underlying collection that is Observable and supports ISupportIncrementalLoading. This clears all items from screen so I know it is bound properly.
2) Replace the underlying collection instance entirely that implements ISupportIncrementalLoading and raise INotifyPropertyChanged so the view knows the property was changed. This also, clears all the items from the screen.
However, the LoadMoreItemsAsync doesn't want to fire after clearing or replacing the underlying collection instance. My hunch is that the UI doesn't think it needs to Load any more, but since I've clear all the items it should want to load more.
I have verified that the HasMoreItems property is set to true.
If it would help, regrettably, you can see the error in production if you download FlixPicks from the Windows 8 store. The steps to reproduce are:
Search using windows search contract
Notice paging works From the Search page
Search again.
Notice all items are cleared. (At this point the LoadMoreItemsAsync is not firing)
Thanks for any advice you can provide!
This definitely looks like a bug. To solve this, add the following line after resetting your collection (in any of the cases):
gv.LoadMoreItemsAsync();
You can probably inherit from the control and create some overrides that will do this automatically:
I know this is an older issue, but I also encountered it and thought others may benefit from an MVVM approach to resolving it. My fix was, after resetting the collection, load a single item into the collection.
private async Task ResetCollectionAsync()
{
Clear();
await LoadMoreItemsAsync(1);
}
The collection is emptied and a single item is re-added. The GridView/ListView control detects the CollectionChanged event and re-queries HasMoreItems to determine whether to load additional data.
This behaviour is baked into IncrementalLoadingCollection (v1.0.1), which also supports filtering and sorting functionality out of the box.
I'm reviving an old question, but I found a solution when none of the previous answers worked for me.
myCollection = new MyIncrementalLoadingCollection();
myListView.ItemSource = myCollection; //This is what I was missing!
Since I wanted the list view to refresh every time the page was navigated to, this was my end result.
protected override async void OnNavigatedTo(NavigationEventArgs e) {
_logItems = new CommandLogIncrementalLoadingCollection();
logListBox.ItemsSource = _logItems;
}

Data into classes, timing, procedure

I have a style/good code question. It's one of those "not that important because it's working" things but still, I'd like some insight from the community. I'm in C# but the methodology could apply to anything OOP
So I have a class, it's essentially a container for data. I pass the class to the database instead of passing 10 parameters. The database writing class drops each data member into it's respective SQL parameter and executes the stored procedure in my database.
My question is, when I am collecting data into the class I have all of them attached to Change events. Like
private void chkIce_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
if (chk.CheckState == CheckState.Checked)
outTruck.setWeather(2, true);
else
outTruck.setWeather(2, false);
}
and
private void txtTrailer_TextChanged(object sender, EventArgs e)
{
TextBox txt = (TextBox)sender;
newRecord.TrailerNumber = txt.Text.ToString();
}
This goes in and sets the ice value of my class to true/false based on what the user selects. Or sets the text. It's pretty straightforward, but there is a bit of code overhead as in each control has it's own event (also the cast on sender line might be overkill). The other way would be to collect all the data at submit. Drop it all into the class then. There was something else called entity framework and ORM, but I am at the moment stuck in .NET 3.5(we are with the times) and I've read that does not apply until you get to 4.0. I've not really read if there is a standard, it seems to be more preference than anything. So, fellow stack overlowieans...what are your thoughts?
Since it looks like you're in a web page with post back, I think it's easier to have that submit button handler functions where you instantiate your object, and manually set each property to the value of its corresponding UI element. Doing the data setting on every event handler (selection changed, focus out, etc.) would require the entire page to reload. (Then, you would have to persist that object across those post backs - a tedious and error prone feat, though doable.)
Even in a desktop project, I would collect all of the values from all UI elements to build my object, in that submit button's event handler.
You would want to implement event handlers on certain UI elements if the change of state in that UI element will affect something other than the object itself. For example, a checkbox may determine whether or not the user will be able to submit - because checking it so might add a feature that costs more where the total price of their order might exceed their current balance. This is when you would check to see whether the submit button should remain enabled or become disabled.