WP7 dynamic pivot - windows-phone-7

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.)

Related

Keeping one Tile Constant in a Wrap Panel

Is their anyway of keeping one tile at a constant position in a wrap panel and having all the added items (currently implementing through a listbox, so listboxitems) wrap around this item.
For example, having the blue tile constant regardless of how many items, with every other tile wrapping around it.
For example:
and:
*Edit #1
I've been looking into custom panels. Maybe i could add a field that if true, would allow for the absolute positioning of an element? Still need to understand how exactly the wrappanel wraps its elements.
*Edit #2
Just realized that idea wont work either. since the attribute of whether the item should have an absolute position would depend on the item itself and so it would require another container, like a "WrapPanelItem" of some sort to define that. Ugh lol
Edit #3
I can maybe set the "Tag" attribute of the children and have a custom Wrappanel check this attribute of the child. If it equals a certain value, it wont adjust its position? But then how do i set the initial position?
Edit #4
No luck with the previous idea.
Edit #5
So i'm attempting to make the custom panel again, but i have a few questions. When items are placed in a grid, how does the arrange method place the item in the item's desired position. I've looked and couldn't find such a property, so how then does the method know where to put the item?
Solved this by making a custom version of the "VariableSizedWrapGrid" provided in Kinnara's branch of the WP7ToolKit. (https://github.com/Kinnara/WPToolkit). It didnt work initially, as it wasn't checking if the entire block fit and instead than just the first unit of the block. If anyone is running into this problem PM me and il send you my updated control :)
O, and instead of trying to wrap around one element, i overlapped the element and had the elements wrapping in the background using the VariableSizedWrapGrid. This implementation was ALOT easier than what i was trying to do.

Are there some samples about moving and removing of a row of listbox

I try to migrate my iphone app to wp7.
On ios, UITableview is well designed, and very easy to code.
I have the some book about wp7, but there are no detail concerned about moving and removing of a row of listbox.
Welcome any comment
I'd like to think that Windows Phone is also well designed. :)
To simply remove an item from a ListBox in your codebehind, you need to get a reference to the ListItem that you want to remove. For example, to remove the currently selected item:
var myListItem = myListBox.SelectedItem;
Then you can remove it with:
myListBox.Items.Remove(myListItem);
In order to address your question about moving items, we'd need to know more about how you're populating the ListBox. Are you using databinding, or adding items with myListBox.Items.Add(myListItem)?
If I needed to move items between two lists, I would create a public List<MyItem> property for each list and databind each list to its own ListBox. Then I might do something like this (working from memory here):
var itemToMove = myList1.Remove(myListBox1.SelectedItem);
myList2.Add(itemToMove);
myListBox1.DataBind();
myListBox2.DataBind();
There's a much better way to do this, using INotifiyPropertyChanged, but I suspect you need to play around with the basics for a while to get comfortable in C#.
Bonus tip: Windows Phone is very similar to Silverlight, and you can usually find more information if you search for Silverlight examples.
In WP7, usually we set the ItemSource of listbox, when our source changes its changes automatically propagate to the UI due to data binding ( it is known as one way binding ; source to UI ).
so what ever you do ( add, update or delete) in itemsource, it reflects to UI.
databinding in wp7

Prevent Pivot navigation in Windows Phone

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.

WP7 pivot headers stop animating when I scoll too fast

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.

Changing ListBox selection is not moving changes from BindingSource to DataSet

The answer to this question may turn out to be, "Don't use typed DataSets without using the Binding Navigator."
I am curious, however, about the behavior I'm seeing.
So, I created a form where every control was dragged from the data sources explorer.
I deleted the Binding Navigator because it is ugly and inappropriate for this particular form.
I added a ListBox and set the DataSource to the BindingSource.
Notice that the ListBox is not bound, it is just filling itself from the BindingSource.
By some magic that I wasn't counting on, moving around in the ListBox is navigating the BindingSource and all other controls are updating accordingly.
I can make changes to the bound controls and explicitly call EndEdit on the BindingSource and then update the DataSource through the Table Adapter. Works great.
When I make changes in the bound controls and click a new option in the ListBox, I want to be able to check for changes and prompt to save or reset if there are any.
Here is the strange part that I haven't been able to figure out.
No matter what event I attach to, DataSet.HasChanges doesn't return true until the second ListBox change.
I've searched and tried dozens of suggestions, most of them ridiculous, but a few that seemed promising.
No luck.
Edit: It isn't the second click that is significant, it is when you click back on the original (edited) item.
Since asking the question, I've learned a bit more about BindingSources, DataSets and TableAdapters.
Here is what works:
private void MyListBox_Click(object sender, EventArgs e)
{
this.myBindingSource.EndEdit();
if (myDataSet.HasChanges())
{
if (MessageBox.Show("Save changes?", "Before moving on", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
myTableAdapter.Update(myDataSet.myDataTable);
}
else
{
myDataSet.RejectChanges();
}
}
}

Resources