How to force keyboard not overlap the stack panel - windows-phone-8

I am new to WP development and trying to get hands-on.
If you look at wallet pin screen, focus is automatically set to textbox so that user can start typing and also the keyboard does not hides/overlaps done & cancel button.
Also, If you hit back key, those buttons remain at bottom as shown below.
I am also trying to have same kind of UI. However, In my case
I am not able to set focus to textbox as soon as page is loaded. I
can't get .Focus() method of textbox in OnNavigatedTo event. Where
should i do this ?
When i manually tap textbox to enter a value, the keyboard overlaps
my stackpanel containing 'save' & 'cancel' button as shown below. I
don't want this to happen. Instead the screen should look like as
shown in 2nd image.
Below is the XAML code i tried.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Name="txtLimit" TextWrapping="Wrap" Text="Enter the value" Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBox AcceptsReturn="True" InputScope="Number" />
</StackPanel>
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Center" Orientation="Horizontal" >
<Button Content="save" Width="200" />
<Button Content="cancel" Width="200"/>
</StackPanel>
</Grid>

For setting the focus for first time navigation you apparently have to set this in the Loaded event handler.
For back navigation (from when you application is switched away), the one in OnNavigatedTo will fire as you'd expect.
// Constructor
public MainPage()
{
InitializeComponent();
this.Loaded += (sender, args) => this.textBox.Focus();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
this.textBox.Focus();
}
However you will need to add your buttons to the ApplicationBar to show below the on-screen keyboard.
However the SDK doesn't allow use of rectangular buttons in the application bar, only icon buttons.

In the OnNavigatedTo method, can you try to use the Dispatcher like this :
Dispatcher.BeginInvoke(()=>{
this.textBox.Focus();
});
And, as pointed out, you can NOT have rectangular buttons in the appBar but you can use standard one (like the linked in button for example).

Related

Create Tab Items and Tab Content dynamically using Orchestra/Catel

I am attempting to create a tabbed interface using Orchestra/Catel. I load the tabs definitions into a TabInfo class. Those work fine - a tabbed interface is created with the correct tab descriptions. In the content for each tab, I want to create a list of buttons - again loaded into a ButtonInfo class. When a tab is selected, the SelectedTab property is used to select the correct list of buttons (ShowButtons).
I have traced the program and when I click on a tab, the correct collection of buttons is in ShowButtons, but nothing shows up in the tab content. I did get this to work in a normal MVVM program, but without the tabs. I used a listview to show my tabs and an ItemsControl to show the buttons.
Belows is my XAML code for the tabs and my SelectedTab logic for pulling the buttons.```
<Grid>
<orccontrols:TabControl LoadTabItems="LazyLoading" ItemsSource="{Binding TabInfo}" SelectedItem="{Binding SelectedTab}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TabDesc}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding ShowButtons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding ButtonDesc}"
MinWidth="150"
Height="30"
FontSize="12"
FontWeight="Bold"
Margin="0,15,25,10"
Padding="5,1">
<Button.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding OracleJob}" Value="0">
<Setter Property="Button.Background" Value="DarkSalmon" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</TabControl.ContentTemplate>
</orccontrols:TabControl>
</Grid>
And the code for populating ShowButtons:
public void OnSelectedTabChanged()
{
int _selectTab = SelectedTab.TabKey;
var _showButtons = ButtonInfo.Where(i => i.ButtonTab == _selectTab);
ObservableCollection<ButtonRecord> _btn = new ObservableCollection<ButtonRecord>(_showButtons);
ShowButtons = _btn;
}
Any help is greatly appreciated. I am a beginner with Orchestra/Catel, so I am probably missing the best way to do this.
I recommend to split up the issue from Orchestra / Catel. Orchestra allows you to provide a view as shell, but this view can live on it's own (the only thing Orchestra does is place it inside the correct location inside the shell). By making this problem unrelated to Orchestra, it makes it a bit easier for us to solve.
Next up, I recommend looking into the Catel docs. There is a full example on how to show a shell with tabs with closable tab buttons, see https://docs.catelproject.com/vnext/tips-tricks/mvvm/using-tabbed-interface-with-mvvm/

while progress bar is running how to disable other controls of the page in WPF

How can i have a loading/progress bar on the page while it is taking time to call a service,also until the call and response is not complete the controls should not be accessible
Try this way, Create a empty grid behind the Progress Bar that cover the whole screen and set its opacity of say 0.5 so that background is paritially visible.
<Grid Grid.Row="0" x:Name="GrdProgressBar" Background="Transparent" >
<Grid Background="White" Opacity="0.5"></Grid>
<StackPanel VerticalAlignment="Center">
<ProgressBar IsIndeterminate="True" Foreground="Green" Margin="0,5,0,0" ></ProgressBar>
<TextBlock Text="loading.." FontSize="20" FontStyle="Italic" Foreground="Black" HorizontalAlignment="Center" ></TextBlock>
</StackPanel>
</Grid>
What you have to done set the visibility of `GrdProgressBara as you do with ProgessBar.
Hope it help you :)
Another way is to use a property IsLoading that is true while the service call is in progress and false after the call finished. Then you can use a converter and bind your IsEnabled property of your controls to the inverse IsLoading value. So while your service call is running, all controls are disabled and when the call finishes, the control will be reenabled. You just need to set the IsLoading property and bind within XAML. No additional code needed.

Access to StackPanel defined in DataTemplate

I've got a LongListSelector for which I select the appropriate DataTemplate based on data I receive according to user's selections.
There are 3 of those DataTemplates which I define in the page's resources and set the appropriate one -just before populating my LongListSelector- using:
RoutesLongListSelector.ItemTemplate = Resources["SecondItemTemplate"] as DataTemplate;
There is an element in these DataTemplates -a StackPanel- where I add some children after populating my list.
<StackPanel x:Name="MyStations" Grid.Column="1" Grid.Row="1">
</StackPanel>
So, when I try to use its name in order to add children [MyStations.Children.Add(...)] I get this error: 'MyStations' does not exist in the current context.
I tried to set one of the Templates as default in the page's ContentPanel but I still get the same error.
Seems to be a minor issue but I couldn't think of something.
Any suggestions?
You can't access UI elements of DataTemplete with their Name property, i.e. x:Name. You can use it's loaded event to access it. Please be specific on your requirement.
<StackPanel x:Name="MyStations" Grid.Column="1" Grid.Row="1"
Loaded="MyStations_Loaded" />
private void MyStations_Loaded(object sender, RoutedEventArgs e)
{
var _StackPanel = (StackPanel)sender;
}

Can we use longlistselector inside a popup in Windows phone 8?

How to use longlistselector inside a popup control?
If not possible, then any other way to show longlistselector/listbox as a popup ?
As a popup you can you CustomMessageBox. Instances of CustomMessageBox have property Content, that has no differences from the Content property of any other content controls. So you can put there LongListSelector or ListBox or whatever you want (even Pivot and Panorama), than call Show method. CustomMessageBox will close if user'll click one of the 2 default buttons, but you can hide them (properties IsLeftButtonEnabled and IsRightButtonEnabled) and close CustomMessageBox by your own logic by calling Dismiss method. There is a couple of useful events: the most useful is Dismissed, that raises right after CustomMessageBox get closed (dismissed), its handler contains DismissedEventArgs, that has result of users choiсe (right or left button was chosen, if they were on the screen) and of course sender (CustomMessageBox). If you want some logic after CustomMessageBox closing, use Dismissed event, Show method won't stop program flow.
This is the easiest way to show something. It's not a popup, but it behaves like it.
But if you wont to use popup ifself, there is Child property for you, put there Grid, and ListBox inside the Grid. But you have to set the values of the Width and Height of popup Child.
You can create a new Page and simply put your LongListSelector in it.
For example (Page is called MyPopupPage):
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<con:LongListSelector x:Name="LongListSelector">
<con:LongListSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</con:LongListSelector.ItemTemplate>
</con:LongListSelector>
</Grid>
Then fill it with whatever you want (Refer to: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj244365(v=vs.105).aspx)
In your MainPage (the page which should open the popup):
Create an object of type Popup like:
Popup LLSPopup = new Popup();
And create a Method to set the MyPopupPage as the overlay of the popup:
private void ShowPopup()
{
MyPopupPage ovr = new MyPopupPage();
this.LLSPopup.Child = ovr;
this.LLSPopup.IsOpen = true;
}

Accessing named controls from page resources

I needed to access to the ActualWidth of a Border that didn't have a specified Width. I have been told that I can't do that on WinRT so I used a proxy from Florian-Gl (from here).
The thing is that I need to create that proxy on the page's resource like this:
<Page.Resources>
<utils:ActualSizePropertyProxy Element="{Binding ElementName=noteBorder}" x:Name="proxy" />
</Page.Resources>
The problem is that I don't have access to that noteBorder element from the resources, but I have access to pageRoot that is the Page itself.
I guess that I can play with ElementName / Path to get access to noteBorder.
But there is some curious stuff:
The structure is something like:
Page (pageRoot) > Grid > ListView > ListView.ItemTemplate > Grid > Border (noteBorder)
So, If I create the proxy at the same level of the border, It won't run but If I change the ListView to a ItemsControl, it will run and works as expected.
If having it at the same level of the border I change the ElementName to pageRoot it will run at least.
So, It won't run if I put noteBorder (even when I have access to it) if I'm using a ListView, but will work on a ItemsControl, On the other hand, If I have pageRoot it works all ways.
So the question is: Is there a way to access noteBorder from resources? Or maybe a way to access it from another place but working :P
You should be using an Item Template --
By the time you get to
pageRoot) > Grid > ListView or Items Control
At this point in the structure, you're at the element you really want to get at, which is the container of the items that will need the border you are trying to access.
You should define an Item Template and assign the ListView's (or ItemsControl's) ItemTemplate property via binding.
<ListView x:Name="myListView" DataContext="{Binding ToElementIfNotInheritedFromParent}" ItemsSource="{Binding ViewModelListBeingBoundTo}" ItemTemplate="{Binding Source={Static Resource MyCustomItemTemplate}}" />
Where MyCustomItemTemplate is something like
<DataTemplate x:Name="MyCustomItemTemplate">
<Border x:Name="myBorder" >
<StackPanel>
<TextBlock Text="{Binding Path=Title}" />
<TextBlock Text="{Binding Path=FirstProperty}"/>
<TextBlock Text="{Binding Path=SecondProperty}"/>
</StackPanel>
</Border>
</DataTemplate>
Then In your Codebehind (or if ViewModel use the code behind to pass the ListView object to the ViewModel)
DataTemplate dt = this.myListView.Items[indexOfChoice].ItemTemplate as DataTemplate;
Border b = dt.LoadContent() as Border;
int actualWidth = b.AcutalWidth
OR
You can create a FindControl() method that runs recursively to extract the actual control within the border, for instance if you wanted to access one of the Textboxes.
The code for that is here:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a612f5a6-e05e-4b68-a813-893eeda159cc