I have recently come across an interesting app and I would like to somewhat modify my solution to resemble their Pivot Header Template. The app can be seen here http://www.windowsphone.com/en-us/store/app/fhotoroom/acad1eed-3149-4b6c-bc4b-8567f409e3e0
where as a user swipes between pivot items the icons in the top right are highlighted accordingly. I have referenced a solution where the icons are paths and as the user swipes between pivot items the icons change colors. The only thing is, I would like to show icons on the right, while on the left the name changes to the respective pivot header name (but only show a single name at a time). I'm kind of lost on how to start this. My thoughts were, get a pivot style copy from blend into the apps page, and then somehow retemplate this so that icons show on the right while the name is on the left. Am I thinking of this correctly? How might I start changing the style to reflect something like this? Is there a better way?
I think pivot header doesn't match behavior that you want to achieve. By default every single pivot item has its own header, and if I don't misunderstand, in this case you got one header for whole pivot control, with displayed text and highlighted icon in the header changes according to active pivot item.
If that is the case, it will be easier to remove the pivot header. Then create a single element on top of the page as pivot header. Bind selected pivot index to a property in model. Then bind the text in the header element to a property that return different string based on selected pivot index. Use similar data-binding concept for highlighting icon (you already have referenced solution for this one). Example :
<Grid Background="DarkBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding HeaderText}" Foreground="White"
FontSize="40" Margin="10,5,5,5"/>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<!--Some icons here-->
....
</StackPanel>
</Grid>
<phone:Pivot SelectedIndex="{Binding PivotIndex, Mode=TwoWay}" Grid.Row="1">
<phone:PivotItem>
...
</phone:PivotItem>
....
</phone:Pivot>
And in the viewmodel :
private int _pivotIndex;
public int PivotIndex
{
get { return _pivotIndex; }
set { _pivotIndex = value; NotifyPropertyChanged("PivotIndex"); }
}
public string HeaderText
{
get { return GetHeaderByIndex(PivotIndex); }
}
private string GetHeaderByIndex(int pivotIndex)
{
switch (pivotIndex)
{
case 0:
return "#recent";
case 1:
return "#favorite";
default:
return "";
}
}
How about that, or is that not the case?
NOKIA made a really good tutorial how to do this. You can go trough the tutorial or just download the code at the bottom of the page.
Tabbed interface with Pivot animation for Windows Phone
Related
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;
}
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;
}
Is it possible to show a PhoneApplicationPage inside another PhoneApplication page.
For example if i loaded page1 of the application using the below code from HomePage.xaml
NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute));
And i want to show a new page say Page2.xaml , i can Navigate to this page using the same above code , but i dont want to open it as a seperate page , but rather wants to Open the Page2.xaml inside Page1.xaml itself as either popup or some other way , so when user closes Page2 it will show the Page1 in the state
If you use a UserControl instead of a Page, you can turn its visibility on/off (instead of navigating).
No you can't like Igor Kulman said. But you can bind all the content and change page as you want with new data.(Title / Content / grid / all :) )
Unfortunately, you can not declare 2 PhoneApplicationPage tags in a single page. Still you could try some tricks .
You can make the dummy of a PhoneApplicationPage Like this
if this is your layoutRoot
<Grid x:Name="LayoutRoot" Background="Transparent">
</Grid>
then you can make 2 pages in a single layoutroot tag and control their Visibility accordingly.
Just remove the row definitions and put two stackpanels. Now these stackpanels spans over the complete grid.
Something like this helps
<Grid x:Name="LayoutRoot" Background="Transparent">
<StackPanel Name="Page1" Background="Red" Visibility="Visible"/>
<StackPanel Name="Page2" Background="Black" Visibility="Collapsed"/>
</Grid>
Below are the two images which describes your solution better.
Making the first stackpanel Visible
Making the Second stackpanel Visible
Hope it Helps
I am developing app in WIndows phone 8 and using LLS with this data template..
<phone:LongListSelector Name="longlist">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding property1, Mode=TwoWay}" Content="Hii" Checked="CheckBox_Checked_1" Unchecked="CheckBox_Unchecked_1"/>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
While I checked one and scroll list the checkbox selection is changed suppose I select first it shows up me 2 is selected or no-one is selected means behave differently..I am using code in .CS in this link...
http://pastie.org/7938678
please suggest me how can I get rid off this problem..
That is by design. You just tapped a check box inside a list item, thereby selecting it.
I suggest you don't rely on list selection position changed, use another event like Tap instead in your DataTemplate to drive any actions you have based on a list item.
If you want only 1 Item selected at a time use a RadioButton instead of a CheckBox. After this you need to define the GroupName Property.
See the code of my answer below:
How to highlight a selected item in the LongListSelector on WP8?
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