How to set tab Index in windows phone 8.1 - windows-phone-8.1

I have 3 Textboxes in my app page and i want to set tab index for them so that when user presses return key from keyboard it should go to next text box.
I have set the Tab Index property of TextBox but its not working.

It works for windows phone 8.1 app with the following code.
private void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key==Windows.System.VirtualKey.Enter)
{
FocusManager.TryMoveFocus(FocusNavigationDirection.Next);
}
}
use the above method in KeyDown event of all TextBoxes.

This is a possible implementation.
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"
>
<TextBox TabIndex="0" KeyDown="OnKeyDown"/>
<TextBox TabIndex="1" KeyDown="OnKeyDown"/>
<TextBox TabIndex="2" KeyDown="OnKeyDown"/>
<TextBox TabIndex="3" KeyDown="OnKeyDown"/>
<TextBox TabIndex="4" KeyDown="OnKeyDown"/>
</StackPanel>
This next code assume that the ContentPanel contains only TextBox. It's up to you to add more smart code in it...
private void OnKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key.Equals(Key.Enter))
{
var txtBox = sender as TextBox;
var index = txtBox.TabIndex;
var nextTextBox = ContentPanel.Children.Cast<TextBox>().FirstOrDefault(t => t.TabIndex == index + 1);
if (nextTextBox != null)
{
nextTextBox.Focus();
}
}
}

Related

How to introduce delay between API calls to google search to avoid OVER_QUERY_LIMIT error

I am using PlacesSearchBar to provide a autocomplete option to look up places in my Xamarin Forms application.
This is working fine from the component's point of view, but google API is returning me OVER_QUERY_LIMIT after one or two attempts.
I think I know what the issue is here, this component is making more than one call to this google API per second that puts me as a suspect mode on the google logic and it starts to return me the OVER_QUERY_LIMIT status. However I am unable to see how to introduce a delay between these calls.
here is how I am using this component.
<searchplaces:PlacesBar x:Name="edtSearch" MinimumSearchText="6" ApiKey="<API KEY>" Placeholder="Please enter your destination address"></searchplaces:PlacesBar>
<AbsoluteLayout>
<ActivityIndicator x:Name="spinner" IsRunning="false" AbsoluteLayout.LayoutBounds="0.5, 0.1, 50, 50" AbsoluteLayout.LayoutFlags="PositionProportional" />
<ListView x:Name="lvPlaces" ItemsSource="{Binding .}" RowHeight="60"
VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
IsVisible="False" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="SizeProportional">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#2B2C30" Orientation="Vertical" Margin="0,0,0,2" Padding="5,5,5,5" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" >
<Label Text="{Binding Description}" TextColor="#EAEDF7" FontSize="Medium" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</AbsoluteLayout>
on my .cs constructor I have this:
edtSearch.TextChanged += async (sender, e) =>
{
if (!string.IsNullOrEmpty(e.NewTextValue) && (e.NewTextValue.Length >= edtSearch.MinimumSearchText))
{
lvPlaces.IsVisible = false;
spinner.IsVisible = true;
spinner.IsRunning = true;
edtSearch.IsReadOnly = true; // try 1: to introduce delay
await Task.Delay(800);
}
else
{
lvPlaces.IsVisible = true;
spinner.IsRunning = false;
spinner.IsVisible = false;
edtSearch.IsReadOnly = false;
}
};
edtSearch.PlacesRetrieved = async (sender, result) =>
{
this.BindingContext = result.AutoCompletePlaces;
spinner.IsRunning = false;
spinner.IsVisible = false;
edtSearch.IsReadOnly = false;
if (result.AutoCompletePlaces != null && result.AutoCompletePlaces.Count > 0)
lvPlaces.IsVisible = true;
if (result.Status == "OVER_QUERY_LIMIT")
{
await Task.Delay(2000); // try 2: to introduce delay
}
};
edtSearch.MinimumSearchText = 6;
on the PlacesSearchBar component code I see this logic:
async void OnTextChanged(object sender, TextChangedEventArgs e)
{
if (!string.IsNullOrEmpty(e.NewTextValue) && e.NewTextValue.Length >= MinimumSearchText)
{
var predictions = await Places.GetPlaces(e.NewTextValue, ApiKey, Bias, Components, Type, Language);
if (PlacesRetrieved != null && predictions != null)
OnPlacesRetrieved(predictions);
else
OnPlacesRetrieved(new AutoCompleteResult());
}
else
{
OnPlacesRetrieved(new AutoCompleteResult());
}
}
as this is a event, no matter what I do from outside this component, it does not effect this behavior of the original component.
Can someone please help me how to get over this OVER_QUERY_LIMIT when using this Auto complete text box.
Regards
Kiran
I think we managed to solve this, issue was that we has not connected our project to a billing account as a result there is a bare minimal request something of the order of 1 request per every second that google allows.
once we connected to a billing account this started to work at least for now.

How to fire code behind method using onclick but not asp:button OnClick

Im in asp.net and I already have a form that utilizes runat="server". I created another form on the page and I have a method in code behind that I need to run on an onclick event.
Since I already have one form on the page, I can't use an asp:button with runat="server"
What's the best way to get my method to fire using an onclick?
Here's my code behind:
protected void requestSong_Click (object sender, EventArgs e)
{
var artist = Request.Form["artist"].ToUpper();
var song = Request.Form["song"].ToUpper();
var song_Request = artist + " - " + song;
SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ConnectionString);
con2.Open();
SqlCommand cmd2 = new SqlCommand("insert into SONGS values (#REQUESTED_SONGS)", con2);
cmd2.Parameters.AddWithValue("REQUESTED_SONGS", song_Request);
cmd2.ExecuteNonQuery();
Here's my aspx:
<form id ="songRequest">
<p style="color:greenyellow"> Request a song</p>
<input type="text" placeholder="Artist" name="artist" id="artist" />
<input type="text" placeholder="Song Title" name="song" id="song" />
<button class="button" onclick="" id="requestSongButton" name="Submit">Submit</button>
</form>
You can use the approach outlined below to fire code-behind method on clicking the button in second client-side form.
Make sure that you have asp:ScriptManager included in your page just after the first form tag ( this is very important else this approach will not work)
Include the JavaScript code given below in your page. In this script, __doPostBack method is being called which is a standard JavaScript function used by asp.net framework to post back on control events like on button click. This function will only be available if you include asp:ScriptManager in your page.
Change the markup of the button in client-side form so it has an onclick attribute set
In your, code-behind in Page_Load event check for the parameters __EVENTTARGET and __EVENTARGUMENT and call the method requestSong_Click passing null for both its parameters ( note: you must not be using sender or e in your button click else this will not work)
JavaScript code to include in page
<script type="text/javascript">
function postBack(btn) {
//get data you want to pass to code-behind
var artist = document.getElementById("artist").value;
var song = document.getElementById("song").value;
var arguments = "saveToDb" + "|" + artist + "|" + song;
__doPostBack('requestSongButton', arguments);
//you can pass more arguments using a comma-delimited or pipe-delimited list of values
//to the second parameter in above method
}
</script>
Markup needed for button in client-side form
<button class="button" onclick="" id="requestSongButton" name="Submit"
onclick="doPostBack(this); return false;">Submit</button>
C# code-behind to handle submit by client-side form button
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
if (Request["__EVENTTARGET"] == "requestSongButton" &&
Request["__EVENTARGUMENT"].IndexOf("saveToDb") = 0)
{
//code that executes on click of requestSongButton in second form
requestSong_Click(null, null);
}
}
}
C# code to get posted values for client-side form button postback
protected void requestSong_Click(object sender, EventArgs e) {
string artist;
string song;
//you must always pass null for e and sender if posting from client-side form button
if (sender == null && e == null) {
var arguments = Request["__EVENTARGUMENT"];
if (arguments != null && arguments != String.Empty) {
//split the | delimited string to an array
Dim argumentsArray as String() = arguments.Split(New Char() {
"|"
c
});
//now get values of artist textbox and song textbox
//note that artist index is 1 and soung index is 2
//due to the sequence in which we populated arguments
//in client-side JavaScript doPostBack function
artist = argumentsArray[1];
song = argumwentsArray[2];
}
} else {
artist = Request.Form["artist"].ToUpper();
song = Request.Form["song"].ToUpper();
}
string song_Request = artist + " - " + song;
SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ConnectionString);
con2.Open();
SqlCommand cmd2 = new SqlCommand("insert into SONGS values (#REQUESTED_SONGS)", con2);
cmd2.Parameters.AddWithValue("REQUESTED_SONGS", song_Request);
cmd2.ExecuteNonQuery();
//more of your code follows

How can I pass an argument to a sub-page in an Appcelerator TabGroup?

I am making a tab based app with Appcelerator. On the master page (info.js) there is a listview showing a list of titles and ids. If one clicks on the item, the id should be passed to the details page (info_details.js). How can I pass the id from the master to the details page in a tabgroup?
I am using code from the sample app, but it does not pass any argument to the sub (details) page:
https://github.com/appcelerator-developer-relations/appc-sample-ti520/blob/master/app/controllers/index.js
function onListViewItemclick(e) {
var item = e.section.getItemAt(e.itemIndex);
//var controllerName = e.itemId;
openSample("info_details");
}
function openSample(controllerName) {
var controller = Alloy.createController(controllerName);
$.info.open(controller.getView());
}
Index.xml:
<TabGroup>
<Tab title="Tab 1" icon="KS_nav_ui.png" id="main">
<Window title="Nominate">
<Label>I am Window 1</Label>
</Window>
</Tab>
<Tab title="Tab 2" icon="KS_nav_views.png" id="info">
<Window title="Info">
<Require src="info"/>
</Window>
</Tab>
</TabGroup>
The subpage (info_details) expects
var args = $.args;
var currentNid = args.nid;
You can pass arguments via the createController args parameter. In your case, you can do something like:
function onListViewItemclick(e) {
//e.itemId or whatever you want to send to the controller
openSample("info_details", {nid: e.itemId});
}
function openSample(controllerName, args) {
//pass the args to createController
var controller = Alloy.createController(controllerName, args);
$.info.open(controller.getView());
}
Then in the info_details:
var args = $.args;
var currentNid = args.nid;

It is possible to get desktop notification from flex web app?

I am working on Flex and I want to know if it is possible to get desktop notification from flex web app?
Please note that from Flex Web App not Flex Desktop App
Yes, through ExternalInterface. Here is a very simple example code in an AS file:
function callNotification(message:String):void {
// throw errors if our JS has errors
ExternalInterface.marshallExceptions = true;
var string:String = <xml><![CDATA[
function(message) {
// Let's check if the browser supports notifications
if (!("Notification" in window)) {
alert("This browser does not support desktop notification");
return false;
}
// Let's check whether notification permissions have already been granted
else if (Notification.permission === "granted") {
// If it's okay let's create a notification
var notification = new Notification(message);
return true;
}
// Otherwise, we need to ask the user for permission
else if (Notification.permission !== 'denied') {
Notification.requestPermission(function (permission) {
// If the user accepts, let's create a notification
if (permission === "granted") {
var notification = new Notification(message);
return true;
}
return false;
});
}
// At last, if the user has denied notifications, and you
// want to be respectful there is no need to bother them any more.
return false;
}
]]></xml>
var success:Boolean = ExternalInterface.call(string, message);
}
callNotification("Hello world!");
I've put together an AS3 class here. Here is the example code using that class:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="155" minHeight="100">
<fx:Script>
<![CDATA[
import com.flexcapacitor.utils.WebNotification;
protected function button1_clickHandler(event:MouseEvent):void
{
var message:String = messageInput.text;
WebNotification.showNotification(message);
}
protected function button2_clickHandler(event:MouseEvent):void
{
var supported:Boolean = WebNotification.isSupported();
resultsInput.text = supported ? "yes" : "no";
}
protected function button3_clickHandler(event:MouseEvent):void
{
var supported:Boolean = WebNotification.isPermissionGranted();
resultsInput.text = supported ? "yes" : "no";
}
protected function button4_clickHandler(event:MouseEvent):void
{
var permission:String = WebNotification.permission;
resultsInput.text = permission;
}
protected function button5_clickHandler(event:MouseEvent):void
{
var results:String = WebNotification.requestPermission();
if (results=="false") {
resultsInput.text = "Not supported";
}
}
]]>
</fx:Script>
<s:VGroup horizontalCenter="0" verticalCenter="0" horizontalAlign="center">
<s:HGroup>
<s:Button label="Create notification" click="button1_clickHandler(event)"/>
<s:TextInput id="messageInput" text="Hello world"/>
</s:HGroup>
<s:HGroup horizontalCenter="0" verticalCenter="0" >
<s:Button label="Is supported" click="button2_clickHandler(event)"/>
<s:Button label="Is Permission Granted" click="button3_clickHandler(event)"/>
<s:Button label="Permission status" click="button4_clickHandler(event)"/>
<s:Button label="Request permission" click="button5_clickHandler(event)"/>
<s:TextInput id="resultsInput"/>
</s:HGroup>
</s:VGroup>
</s:Application>
More info
https://developer.mozilla.org/en-US/docs/Web/API/notification

How to set a background image by code on windows phone?

My question is very simple but I don't find a solution that works.
I code a Windows Phone app and I have to change the background. The change depends of the user profile on the application. If the user is a male, the app display a blue background, if she is a female, a pink one.
I've tried to bind the background but I still have a blink effect (black to the background image).
It is very visible when the app navigates between two pages but invisible when the change is made on the same page.
I tried these solutions too but the background stay black:
string uri = String.Format("/Assets/Background{0}.png", App.Context.SelectedUser.IsMan ? "Boy" : "Girl");
var imageBrush = new System.Windows.Media.ImageBrush
{
ImageSource = new BitmapImage(new Uri(uri, UriKind.Relative))
};
this.Background = imageBrush;
string uri = String.Format("/Assets/Background{0}.png", App.Context.SelectedUser.IsMan ? "Boy" : "Girl");
var imageBrush = new System.Windows.Media.ImageBrush
{
ImageSource = new BitmapImage(new Uri(uri, UriKind.Relative))
};
App.RootFrame.Background = imageBrush;
I tried with .jpg and .png image file but none works.
Is my code wrong?
Anyone has a suggestion?
Thanks a lot :-)
This code works in a blank silverlight app in Windows Phone 8.
In Xaml:
<Grid x:Name="LayoutRoot" >
<Grid.Background>
<ImageBrush ImageSource="/Assets/boy.png" Stretch="UniformToFill" />
</Grid.Background>
<Button Content="Change" Click="Button_Click" />
</Grid>
and in the code behind:
private void Button_Click(object sender, RoutedEventArgs e)
{
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.UriSource = new Uri("/Assets/girl.png", UriKind.Relative);
var imageBrush = new System.Windows.Media.ImageBrush
{
ImageSource = bmp
};
LayoutRoot.Background = imageBrush;
}