I have an audio recording application for Windows Phone. It consists of a pivot control with two pivot items. One is for recording control, and another one is for reviewing and listening the recorded items.
When the recording is taking place, I need the way to prevent the user from navigating away from the current pivot item, but to retain the feel that an entire pivot item moves, but doesn't flip to the next item, as if there is none.
I know I could use GestureListener from Silverlight Toolkit, but using it I will need to implement a simulation of pivot movement myself.
Is there a build-in way to prevent pivot navigation?
If no, can you point me to an example on how I can animate control movement on gesture flipping?
Is it mandatory that the user has to remain on the one PivotItem?. If not, you could just disable the second PivotItem so that the user knows that it's there, but can't actually interact with it.
secondPivotItem.IsEnabled = false;
Alternatively, you could dynamically insert the second PivotItem when you want it and remove it when you don't. For example, when recording:
mainPivot.Items.Remove(secondPivotItem);
then when you want the second PivotItem to appear:
mainPivot.Items.Add(secondPivotItem);
The only "problem" with this is that when you only have one PivotItem on screen, the user can't scroll. However, this is how a Pivot control is supposed to function.
If you really want the user to scroll back to itself, you could create a blank PivotItem (with no header). Then, handle the Pivot's LoadingPivotItem event. Check if the item that it about to be loaded is the blank one. If so, then use Pivot.SelectedItem = recordingPivotItem to navigate back to the recording PivotItem. You can then use the above method to dynamically add the second PivotItem when the recording is over. This isn't the normal UX for pivots, but should do what you're trying to achieve.
Seems to me that the best solution is making the pivot control invisible to hit test altogether. I simply set PivotMain.IsHitTestVisible = false and set it back to true whenever I am done recording.
There is a good attached property approach on how to make a particular element hit test visible, while casting an entire panorama or pivot item hit test invisible:
Here is the link to a blog post of an author with the source code:
http://blogs.msdn.com/b/luc/archive/2010/11/22/preventing-the-pivot-or-panorama-controls-from-scrolling.aspx
Works for me until the dynamic loading and removing of the pivot items with textblock header will be added to the SDK's pivot control.
The down side of locking a person into a pivotitem or disabling one so that a person cannot navigate is that you are going to frustrate the user. PivotItems are meant to be flicked to and from, and writing an app that has behavior different than this is going to take away from the user experience, because the app is not going to behave the way they expect it to.
Personally, if you are going to lock them into one pivot item, I think you should go ahead and create another page without a Pivot control and navigate to it. Also, whether you choose to do it this way or not, you need to keep in mind that regardless of whether they are locked into a certain pivotitem or they are navigated to another page, the back button must work as expected, or the app won't pass certification.
Related
I've got a pivot control with a number of pages in it. Each page has some controls in it, for example a textbox.
I've read around and I KNOW that it's bad practice to put controls like this in a pivot but I'd really like to do it.
The application switches between pivot pages automatically but the user is able to move the pivot control manually and I don't want this. I tried to prevent user gestures by changing the pivot control's IsHitTestVisible property to false and although it stops the user changing the pivot page, it also prevents the use of the textbox inside.
Does anybody know how to prevent the user changing the pivot page, but still allow use of the controls inside?
Thanks for any help you can provide!
Silverlight for Windows Phone Toolkit has a control for this (LockablePivot).
when i use pivot with in the panorama .pivot are used as a gallery view. i want to move pivot when i swipe it .but the problem is this because of both panorama and pivot are the same gesture event so both are they move .
i want swipe only my pivot view .
I would like some sample code or any other suggestion to do this.
so please give me a solution for doing this and
also give me a link where i easily understand this. Thanx in advance
You shouldn't have a Pivot in a Panorama control. End of discussion.
I believe it is achievable, because I've already solved similar issues with having WebBrowser control inside a custom horizontal-scrollable overview container like Pivot/Panorama, but believe me, it is NOT worth it. I've had to dig very deep into the visualstructure of the controls and attach my own manipulation-handlers to their viscera, manually choose which horiz/verti events to pass and which to cancel, and so on. This is not so easy, takes a lot of time, and doesn't guarantee that on the end you will have something behaving in a way you wanted to achieve in the first place. If you are not bound by some contract to preserve the shape of the UI, please, drop the idea and redesign your UI, just to save on your sanity and nerves.
But, if you are already insane or really want to dig where noone should, start on analysing your UI as a two rectangles: large pano and small pivo, and think which part should behave how on different possible touches/h-v swipes/h-v pans/pinches/so on. Write it down just to for reference, or soon you will probably start making small mistakes that will interfere with your understaning of the flow of the events.
I've checked the version I have, and "my" Panorama uses internally the UIElement.ManipulationXXXX events. In that case:
Display visualtrees of your UI and try attaching manipulation-events to every control. In those events, write/log which control's which handler was invoked. Then make some swipe/scroll on your APP and observe events. Analyze how they were bubbling and try cancelling (e.Handled=true) the manipulation-completed and/or manipulation-delta events somewhere between pivot and panorama. Your goal is to have the panorama see that e.Handled=true, while your pivot must see e.Handled=false. Your Pivot will probably see the event sooner than the Pano, so that point should be relatively easy.
If it fails to work, then you should check your version of the Pano, and check how it detects movements. If, for example, it uses the GestureListener - try the same trick with it. Etc.
And remember, you can always make your own horizontal-overwiew-container that will look like Pano, behave like Pano, and that will work with Pivo better - because it will be your code and you will tell it what and when to move. if you want to go this way, start on google and check all the preliminary Panorama previews that random people have published before that control was published by MS.
I'm having trouble implementing a dynamic pivot control.
What I would like to do, is create an image gallery using the pivot, where you could change the image by swiping.
This works natively with the pivot control by binding it's itemsource on my observable collection to display one image on each pivotitem.
The thing is that this solution takes a lot of memory when my gallery contains more than 10 pictures, as it creates an equal number of pivotitems.
What I tried is initializing my collection with 3 items, the currently displayed one, the previous and the next one, and when the user swipes, I updated my list.
I tried this using the "SelectionChanged" event and also with the gesture listener.. without success so far.
Has anyone ever tried to do this? And if yes, how can I implement it?
I do something similar, but don't use a Pivot control. Download the Silverlight toolkit (http://silverlight.codeplex.com/) and use a GestureListener to catch the swipe action:
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DragCompleted="OnDrag"/>
</toolkit:GestureService.GestureListener>
Then in code, you have an event handler that catches the swipe event, and updates the image accordingly. Here is the event handler that I use to change my page:
private void OnDrag(object sender, DragCompletedGestureEventArgs e)
{
if (e.Direction == System.Windows.Controls.Orientation.Horizontal)
{
if (e.HorizontalChange < 0)
{
TurnPagesForward(1);
}
else
{
TurnPagesBackward(1);
}
}
}
If you update the items in your list your binding will be lost, so this will probably not work very well.
What might work is the following (but I have not tested it):
Start with an initial collection with five items.
Make sure you display the third item in the list so that the visible item is in the middle of the list.
When changing the visible page the SelectionChanged event is raised.
If you move to the right the selected index is changed to the fourth element. In this case you remove the first element in the list and add a new fifth element.
If you move to the left you do the opposite and remove the last element in the list.
This should ensure that you always can move back and forth while not removing or adding any visible items.
I am not sure if this will work, but it is worth a try. :-)
Don't do this. Lots of people have tried and it doesn't scale to large numbers of images.
Although it would be really nice if it was possible to use the pivot control to create a simple image navigation control it just isn't practical. You'll need to go the more complicated route of doing this yourself with a different method. (Lots of people have tried different ways. Go with what's best for your needs/experience/preferences.)
i have a pivot control with around 20 items that are data binded to an observable collection. One of these items has a long text inside, and I think it delays a bit to data bind. when i scroll too fast and pass this item, the headers start to behave strange, the highlighted header disappears from the screen and i see the other headers. the animation of headers stops.
How can i fix this? any ideas? You can reproduce this problem on a device.
thanx
I would have though that having 20 pivot items was more likely to be the cause of the problem, rather than a long pivot title. However, from a user experience point-of-view I would suggest that 20 pivot items is not going to provide a good user experience especially as all pivot items are loaded on when the pivot is started, so performance is likely to be poor, too.
I would suggest that you consider an alternative approach. Perhaps you could use the Panorama to provide a Hub-like experience with your data grouped into different Panorama items. You could then use a Pivot on secondary pages to show group contents where appropriate.
I can't say that I've experienced this, but then I haven't found a need to use a Pivot with 20 pages.
Could it be that if you're finding the need to flick that quikly through the pages that another UX would be more appropriate?
Perhaps a listbox to present a choice of items allowing ultra smooth and fast scrolling, from which the user can choose to select an item and drill down for details.
The databound project template provides some out of the box handling to demonstrate the concept, but don't be show to roll your own in a vanilla project template.
I've experienced the same issue with a pivot control with only 4 pivot items. The animation gets screwed up when the pivot item containing a long list is selected, so I'm guessing that because pivots don't load their data until the item is selected, that the pivot control is getting screwed up trying to load the long list while animating...so it gives up on the animation.
I haven't really figured out what to do about this yet. One solution is to not bind the data in the pivot item until that item is selected. This isn't really ideal, but it would likely solve the animation issue.
What would be the appropriate way for selecting a particular row in a paginated view.
For example, while trying to select a particular row in Yahoo Inbox you can use the pointer to select the check box and if you try to click beyond the check box, no action is taken.
But while trying to select a particular row in GMail Inbox you can use the pointer to select it or if you navigate away from the checkbox it changes into a thumbnail but allows you to select the row.
Which method is preferable from a usability perspective and how to implement the thumbnail based selection as done by GMail
Both methods are appropriate, and both can be very usable.
I think the main difference is that row selection (the system used by Gmail) is more like a desktop application and a little less web-like. With links (like in the Yahoo inbox or StackOverflow), it's completely obvious that you're supposed to click on them. With rows, you sort of have to figure that out that you can click them, but I doubt it takes people long.
One thing to keep in mind is that, if you go with row selection, it's probably a good idea to bunch together any other clickable control (like checkboxes, links, or "favorite" stars). This way, you can click anywhere on the row. If you intersperse controls along the row, you increase the likelihood users will make clicking errors (aiming for the row but accidentally clicking some other control), and it will make it harder for users to recognize that the row itself is a clickable region.
So, both are perfectly acceptable user interfaces. You'll have to decide which one is a better match for your particular situation. I think, in general, links are a little bit more versatile, but with clickable rows, you know you can click anywhere and it will work.