I have a custom DatePicker, which is opened if the user taps on it. It uses the same mechanics like the Xamarin.Forms DatePicker. The scenario is like the following:
user taps on the custom DatePicker
instead of picking a date he opens another dialog
two dialogs are now opened at the same time
I tried to Unfocus() if the other element get's the focus, but nothing happens. The DatePicker is still displayed.
What else can I do? Should I throw manually the Unfocus event? Can I lock the UI somehow so that the user has to press the Finish button before moving on?
First, the issue doesn't occur if I switch between DatePicker and TimePicker. It only occurs if I switch from DatePicker/TimePicker to my Entry (which triggers a custom dialog in Focused event).
And Unfocus() does work, if you do it on the UI thread:
private async void someEntry_Focused(object sender, FocusEventArgs e)
{
Device.BeginInvokeOnMainThread(() =>
{
this.datePicker.Unfocus();
});
// custom dialog shown to user ...
}
Related
In my code I have bound the defaultProperty of a button to some other properties like so:
BooleanBinding isAddResourceButtonDefault
= resourceNameTextField.focusedProperty().or(
resourceTypeComboBox.focusedProperty()).or(
divisibleResourceCheckbox.focusedProperty().or(
maxInstancesTextField.focusedProperty()).or(
addResourceButton.focusedProperty()));
addResourceButton.defaultButtonProperty().bind(isAddResourceButtonDefault);
The problem is that the addResourceButton won't fire absolutely any events on pushing Enter - neither OnAction, nor OnKeyPressed.
The default property gets set just fine - I double checked (using output and ScenicView). ScenicView also doesn't show any events being fired upon hitting keys. Any ideas?
I believe TextFields (and other TextInputControls) process and consume key events that occur on them. So pressing Enter on a text field will not fire an action event on the default button (because the key event never reaches the Scene).
If you are just trying to fire the button's action event handler when enter is pressed in one of the text fields, just add the same event handler to the text fields. E.g.
EventHandler<ActionEvent> addResourceHandler = event -> {
System.out.println("Add resource");
// ...
};
addResourceButton.setOnAction(addResourceHandler);
resourceNameTextField.setOnAction(addResourceHandler);
maxInstancesTextField.setOnAction(addResourceHandler);
I am implementing an autocomplete view in my mobile app that i am developing using Xamarin.
I have set threshold to 1 and set the focus to autocomplete view in onCreate event of activity.
autoCompleteView.FocusChange += delegate(object sender, View.FocusChangeEventArgs args)
{
if (args.HasFocus)
{
autoCompleteView.ShowDropDown();
}
};
It displays the dropdown with all the suggestions when my app is loaded. Whenever i type text, it filters based on condition and everything is working fine. But when i clear all the text in the autocomplete view, the dropdown is closed. But i want to display the dropdown with all the suggestions.
Also whenever i touch/click the autocomplete view, the dropdown is closed. So i have added the below code to display the dropdown, but there is a flicker(dropdown is closed and is opened again).
autoCompleteView.Click += delegate(object sender, EventArgs args) {
autoCompleteView.ShowDropDown ();
};
Thanks in advance.
It displays the dropdown with all the suggestions when my app is
loaded
You can call autoCompleteView.ShowDropDown(); in you OnCreate (independant of focus), this way the app loads with the dropdown showing.
Also whenever i touch/click the autocomplete view, the dropdown is
closed. So i have added the below code to display the dropdown, but
there is a flicker(dropdown is closed and is opened again).
Subscribe to the TextChanged event and call autoCompleteView.ShowDropDown(); whenever the text in the EditText is String.Empty.
I have a TextBox in my app, and an ApplicationBarIconButton in the ApplicationBar which acts as a "submit" for the contents of the TextBox.
When editing the TextBox using the virtual keyboard, the ApplicationBarIconButton is still visible below the SIP, so you can submit straight away without dismissing the keyboard: nice!
However, when clicking the button, the viewmodel to which the TextBox is bound does not update.
I found someone else with the same problem here, and they have used the pretty nasty workaround of manually updating the viewmodel on the TextBox's TextChanged event.
Removes all the elegance of using databound view models!
Is this a bug in WP7?
Or is there a nicer way around this that I haven't found yet?
The problem is that silverlight bindings do not support the PropertyChanged value for UpdateSourceTrigger. This means that by default a TextBox will update the property bound to Text when the TextBox loses focus and the only other possibility is to update it explicitly in code as is done in the example from your link.
You only really have two options here: Update the binding when the button is clicked or remove focus from the TextBox when the button is clicked.
I usually update the binding on the TextChanged event. I use an extension method to do this:
public static void UpdateBinding(this TextBox textBox)
{
BindingExpression bindingExpression =
textBox.GetBindingExpression(TextBox.TextProperty);
if (bindingExpression != null)
{
bindingExpression.UpdateSource();
}
}
allowing me to just call this in code behind:
textBox.UpdateBinding();
You may also be able to use a custom behaviour for this.
Summary of the steps to allow binding to work for each keypress of a textbox, instead of just when the text box loses focus. Uses Prism. It is a slightly indirect solution to the original problem.
In NuGet package manager, search for Prism. Add "Prism.Phone" created by "Microsoft patterns & practices"
Add the following to the page's phone:PhoneApplicationPage tag
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:prismInteractivity="clr-namespace:Microsoft.Practices.Prism.Interactivity;assembly=Microsoft.Practices.Prism.Interactivity"
Give your textbox a separate closing tag, and add the following between the opening and closing TextBox tags
<i:Interaction.Behaviors>
<prismInteractivity:UpdateTextBindingOnPropertyChanged/>
</i:Interaction.Behaviors>
I guess this will work but you should check if it is really necessary having an ApplicationBarIconButton (or simply a button on the page) for that.
Often you should avoid this when you like to have a good Metro design in your app you may prefer using InputScope="Search" + Hiding the SIP is easily done using Page.Focus()
e.g. (an old article; InputScope="Search" worked for me)
http://4mkmobile.com/2011/02/wp7-devs-stop-adding-search-buttons/
See also: http://forums.create.msdn.com/forums/p/70506/619517.aspx#619517
private void SearchTextBox_KeyUp(object sender, KeyEventArgs e) handler:
Using InputScope="Search" for my search field
Using DataBinding Mode=TwoWay
Focus(); // hides the SIP
UpdateBinding(SearchTextBox); // the trick mentioned in here
App.ViewModel.ExecuteSearch();
Works fine in my MVVM app.
I've read somewhere that longlistselector from the toolkit is better in performance than the existing listbox. So, I changed the listbox to longlistselector. Now I have a image button control to keep in the longlistselector (that acts like a checkbox). When I click on the button, the list selection changed event is fired along with the button click. The button in listbox works fine as expected but not in longlistselector. How can I stop the list selection changed event? I searched a lot on this but couldn't find anything useful. First of all is it possible?
I wouldn't take it for granted that the long list selector performs better than the listbox. The listbox uses a virtualizing stack panel when binding is involved and is pretty performant. I went down the road of using the list picker from the toolkit and ended up regretting it due to some bad performance problems. If it works with the listbox I'd say stick with the listbox and only move away if you find you have perfomance issues in the future.
When a button is clicked a button event handler is triggered and when a item in the long list selector is changed the corresponding selection changed event is triggered IF it is also registered. But the button is clicked on the same selected item, only the button event handler is triggered. I suggest to have only a button event handler and get the selected item from it.
private void ButtonEvent_Click(object sender, RoutedEventArgs e)
{
HoldingClass clicked=((sender as Button).DataContext as HoldingClass);
//Do something with the HoldingClass as this is the binding element to the long list selector
}
Change the ClickMode to Press in XAML
ClickMode="Press"
and inside you Click event handler make (YourListName).SelectedItem = null;
private void deleteButton_Click(object sender, RoutedEventArgs e)
{
MainLongListSelector.SelectedItem = null;
..
}
I have a page with "internal navigation". That means that I show some list on that page and when user picks an item, I (download some data and) repopulate that list.
I made my own history stack, so when user wants to go back, I repopulate the list from history stack. User can go back by flicking or by clicking on hw back button.
Flicking works ok, but back button is weird.
I am canceling the back button event and instead I run my back navigation history. So I am still on the same page. BUT the back button click hides the application bar (even though I am canceling that event). And when I click it again and debug it, the ApplicationBar property is null.
// this overriden method causes ApplicationBar being hidden (or destroyed)
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
Messenger.Default.Send(...some notification here...); // this runs the internal navigation
ApplicationBar.IsVisible = true; // this doesn't help and on the second try, it throws NullReferenceException
}
// this method is ok, repopulating is working without any problem
private void GestureListener_Flick(object sender, FlickGestureEventArgs e)
{
Messenger.Default.Send( ...some notification here... ); // this run exactly same internal navigation
}
So question is - how to have ApplicationBar not destroyed/hidden? What is back button doing, when I cancel the navigation (it must do something with the AppBar)?
OK, this happens only when I use BindableApplicationBar and its Extensions (from here maxpaulousky.com).
It happens because Extensions handles back button event on page itself.
Solution was to check the Cancel property, and destroy it only when it's false (in BindableApplicationBar class in the Extensions).