Example Pivot Control for Windows Phone 7
Submitted by smartyP on Thu, 04/08/2010 - 18:21I know I said I was done trying to recreate the Pivot control, but I'm happy to be able to share a standalone Pivot control that I've been working on. Keep in mind that a real Pivot control from Microsoft should eventually be released, so this control is not intended to be used in your final production code.
First, download the attached SmartyPantsPivotLibrary_Release1.zip, extract it, and add a reference in your project to SmartyPantsPivotLibrary.dll. Next, add a reference in your MainPage.xaml to the library like this:
xmlns:spcoding="clr-namespace:SmartyPantsPivotLibrary;assembly=SmartyPantsPivotLibrary"
Next, add an instance of the PivotControl inside of the ContentGrid in your MainPage.xaml:
<Grid x:Name="ContentGrid" Grid.Row="1">
<spcoding:PivotControl>
<spcoding:PivotControl.PivotPages>
<spcoding:PivotPage PageTitle="main">
<spcoding:PivotPage.Content>
<TextBlock>main section goes here</TextBlock>
</spcoding:PivotPage.Content>
</spcoding:PivotPage>
<spcoding:PivotPage PageTitle="options">
<spcoding:PivotPage.Content>
<TextBlock>options section goes here</TextBlock>
</spcoding:PivotPage.Content>
</spcoding:PivotPage>
<spcoding:PivotPage PageTitle="about">
<spcoding:PivotPage.Content>
<StackPanel Orientation="Vertical">
<TextBlock>about section goes here</TextBlock>
</StackPanel>
</spcoding:PivotPage.Content>
</spcoding:PivotPage>
</spcoding:PivotControl.PivotPages>
</spcoding:PivotControl>
</Grid>
As you can see by the XAML definition above, you are basically adding a PivotControl, and then populating PivotPages with multiple PivotPage entries. A PivotPage is defined as having a PageTitle property (what appears across the pivot menu across the top) and a Content property (what shows up in the main content area for each pivot page).
One other thing you may want to use are two events that tell you when the pivot pages are being dragged around - by listening to these events you can make sure the user doesn't accidentally click on something while changing pages (more on this in the video below):
MainPivot.PivotPageMoving += (s, e) => { _ignoreClicks = true; };
MainPivot.PivotPageDoneMoving += (s, e) => { _ignoreClicks = false; };
Below is a quick video showing how to use the control and discussing a bit more about it, you'll find the example project attached to this post:
As a side note, I have been unable to get this control to work in a large project I had already been working on - for some reason an unhandled Application level exception occurs after changing pages from time to time - unfortunately the exception provides no details and the call stack only shows internal methods. So, this control is provided AS IS - I won't really know how well this works until others try and use it. I also am not committed to maintaining this control, but if you improve on the code and would like to have the code posted updated please feel free to let me know.
Attachment | Size |
---|---|
SmartyPantsPivotLibrary_Release1.zip | 21.03 KB |
PivotControlUsageApp.zip | 44.58 KB |
SmartyPantsPivotLibrary_Source.zip | 13.25 KB |
Comments
Hi! I followed you since your
Hi!
I followed you since your first mention about your pivot control. Thanks for great job! =)
But I have a little question.
Is there a possibility to make a binding to pages and page's contents?
To be more specific let's assume following example. I have products which grouped into several product groups (the number of them is not known at design time). And I want to show user a pivot control which displays each product group as a page and list products of selected group as page's content (ie as a listbox).
It would be great if you provide a little example of how can I do it with your control.
Thanks!
@makarovandrey
@makarovandrey, that is a
@makarovandrey,
that is a interesting request.. right now the control is very much static.. it allows you to dynamically define pivot pages in XAML, but if it supported binding then it would need to be able to handle changes that might occur in the bound definition - it would have to know how to handle adding/removing pivot pages at runtime.. the current code constructs the UI in the control's Loaded event - so it is not possible to change the pivot pages beyond that..
the best you could do with the current tool is to construct the pivot pages programatically, and then add the pivot page to your UI.. here is an example of something like that:
// create a collection of pivot titles and corresponding UI content areas:
Dictionary pivotPages = new Dictionary();
pivotPages.Add("main", new TextBlock() { Text = "main section goes here" });
pivotPages.Add("options", new TextBlock() { Text = "options section goes here" });
pivotPages.Add("about", new TextBlock() { Text = "about section goes here" });
CreateAndDisplayPivotControl(pivotPages);
..
..
/// Method for setting up the pivot control and adding it to the stage from a pivot menu collection definition
private void CreateAndDisplayPivotControl(Dictionary pivotPages)
{
PivotControl pc = new PivotControl();
foreach (string menuTitle in pivotPages.Keys)
{
PivotPage pp = new PivotPage() { PageTitle = menuTitle, Content = pivotPages[menuTitle] };
pc.PivotPages.Add(pp);
}
ContentGrid.Children.Add(pc);
}
..
..
that may not meet your need, but unfortunately there would be a lot of work trying to support binding so it's not something i'll be able to do for you.. i am going to be curious though if the final control supports dynamic binding of titles and content.. thanks for the comment!
Nice work Roger! It worked
Nice work Roger!
It worked right away. But I added a Storyboard that animates content inside one of the contentpages. But as soon as I start the Storyboard I get the message "2213 An error has occurred."
Did anyone experience this as well?
-
Mark Monster
ive run into that error a few
ive run into that error a few times.. i dont exactly know how to solve it every time, but it seems it occurs when you have two different storyboards trying to modify the same object at the same time.. maybe try to group your objects into a grid and then animate against that grid instead of the main root of the page that the pivot control is trying to animate?
Thanks for your reply Roger.
Thanks for your reply Roger. I tried your suggestion, but it didn't help. But still I just hope to get this control from the Microsoft Guys themselves :-). For now I have at least something to prototype.
-
Mark Monster
First of all, thanks for the
First of all, thanks for the control! However, i can't make a simple textbox to work properly inside of it. Let's start with xaml:
...
...
...
It looks perfectly in emulator and all the motions go smooth. Now let's get straight to the problem and add a bit of c# code:
private void Search(object sender, RoutedEventArgs e)
{
string text = SearchTerm.Text;
}
I'm getting a NullReferenceException for the SearchTerm.Text. Vs reacts as if SearchTerm TextBox doesn't exist at all... Is that just my mistake or there are some problem with this control?
[spcoding:PivotPage.Content]
[spcoding:PivotPage.Content]
[StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Horizontal"]
[TextBox x:Name="SearchTerm" Margin="20,0,0,0" Width="275" TextWrapping="Wrap"/]
[Button x:Name="SearchButton" Width="150" Content="SEARCH" Click="Search"/]
[/StackPanel]
...
[/spcoding:PivotPage.Content]
oops, sorry for the code. Can't post it the other way :(
if it compiles, but then
if it compiles, but then fails at runtime it may be that you are trying to access the SearchTerm textbox before InitializeComponent() has run - that would cause the value to still be null.. i dont think this issue is relative to the control, but hopefully that helps - if not see if you can host your code somewhere for me to download and look at.
I implemented this in a
I implemented this in a sample app that I have, and yeah, I was getting an unhandled ArgumentException when switching pages, so I had a look at the source and the only things I found (and subsequently altered) were:
1) You're initialising the PivotPages property in the DependencyProperty.Register() method which isn't really a problem on its own, but if multiple pivots are created (which probably won't happen... I'm not sure) then you'll end up with an unintended singleton which will cause issues. I was working on a layout-type control where I was getting very similar exceptions, so it's probably completely unrelated hehe :)
2) Changing that first property let me actually step through the code and it looks like almost everywhere you call UIElement.TransformToVisual(), you get an ArgumentException with some obscure stack trace staring you in the face. For the purposes of this control (before an official one comes out), the TransformToVisual() stuff didn't need to be there, so I removed it and the control's been behaving fine since then. I'm not sure why this exception gets thrown, these things with the really unhelpful messages get on my nerves hehe :)
Anyway, that's what I found. The control looks good but I created a panorama control too and I'm just gagging for them to release some official stuff :)
Awesome Ben, thanks for the
Awesome Ben, thanks for the feedback and information on what you found :)
Hi, when using the pivot
Hi, when using the pivot control and within a pivot page i have a list box. If I try to get a reference of that list box from code, the list box is never initialised. Its always null. What can i do to solve this?
You may find the following
You may find the following blog about Windows Phone 7 controls interesting:
http://blog.fluentcomponents.com/