How to programmatically set selected Panorama item in WP7 - c#

I'm using a panorama control in a WP7 app. One of the PanoramaItems takes you to another page, which then allows you send an email through the EmailComposeTask. If you don't select to send the email and press the back button, the Panorama returns to the item you last selected. However, if you do select to send an email (and therefore leave the app), it does not return to the previously selected PanoramaItem. Instead, it returns to the first item in the Panorama. I tried keeping track of the selected index and setting it, but I got an error saying the SelectedIndex is not settable. This is confirmed on MSDN documentation http://msdn.microsoft.com/en-us/library/microsoft.phone.controls.panorama.selectedindex%28VS.92%29.aspx
Is there any way to manually set the selected index/item on a panorama? If not, is there a way for it to remember what was selected, even if the user leaves the app to compose an email?

I'm not sure if you can programmatically force an animation to another PanoramaItem, but you can change the Panorama.DefaultItem.
So you might have 3 PanoramaItem's and on the OnNavigatedTo() handler, change the default item via:
panoramaControl.DefaultItem = panoramaControl.Items[indexToSet];
This should help when you recover from a tombstone.

You could try the solution posted by Silicon Shark in this thread. It's noted to work, but only on the initial display - which shouldn't be a problem for your requirements of restoring state after tombstoning.
How to programmatically set the visible item in a Panorama control?
You can get the currently active page from the panorama's SelectedIndex property.
Unfortunately setting DefualtItem is only an approximation to solving this problem, which you may have discovered already.
Edit: Be aware that setting DefaultItem, changes which page of the panorama is the first page. It's a subtle difference, but you will see how it matters looking at the positioning of the heading and the wrap around of the background image.

Here is a solution. It does work as expected and does not rearrange your panorama, so your user interface is consistent.
pan.SetValue(Panorama.SelectedItemProperty, panoramaItem);
Panorama temp = pan;
LayoutRoot.Children.Remove(pan);
LayoutRoot.Children.Add(temp);
LayoutRoot.UpdateLayout();
this is not a perfect solution in that it does not slide nicely like panorama should, and it is probably not very efficient, but on the other hand you are not changing the default item so your user interface stays consistent.

I tested solutions listed here without success. Here is what I did that works like a charm!
PanoramaItem panItem = (PanoramaItem)panorama.Items[1];
panorama.Items.Remove(panItem);
panorama.Items.Insert(0, panItem);
You need to remove the panel from the list and re-inserting it at the desired position!

Set new selected item by
pan.SetValue(Panorama.SelectedItemProperty, pan.Items[newSelectedItem]);
However, it work only on the initial so my idea is let the panorama control re-init when we change the selected item. This is my code, just add this after Panorama.SelectedItem changing.
(pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Collapsed;
pan.SetValue(Panorama.SelectedItemProperty, pan.Items[(curIndex + 1) % pan.Items.Count]);
pan.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
(pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Visible;
But there is not transition effect now! Although, you can create your self.
It work great for me, this page also create a effect for sliding right http://xme.im/slide-or-change-panorama-selected-item-programatically

I'm using this model to change to a pivot when the device goes into landscape view, I'll probably end up extracting the current item to the application state. The panorama is a no-go in landscape orientation.
private int hub_page_index;
protected override void OnOrientationChanged(OrientationChangedEventArgs e)
{
base.OnOrientationChanged(e);
if (panorama.Visibility == Visibility.Visible)
{
hub_page_index = panorama.SelectedIndex;
}
else if (pivot.Visibility == Visibility.Visible)
{
hub_page_index = pivot.SelectedIndex;
}
if (e.Orientation == PageOrientation.Landscape
|| e.Orientation == PageOrientation.LandscapeLeft
|| e.Orientation == PageOrientation.LandscapeRight)
{
// Display Pivot in Landscape orientation
pivot.SetValue(Pivot.SelectedItemProperty, pivot.Items[panorama.SelectedIndex]);
panorama.Visibility = Visibility.Collapsed;
pivot.Visibility = Visibility.Visible;
}
else
{
// Display Panorama in Portrait orientation
panorama.SetValue(Panorama.SelectedItemProperty, panorama.Items[pivot.SelectedIndex]);
pivot.Visibility = Visibility.Collapsed;
panorama.Visibility = Visibility.Visible;
}
}

Related

Xamarin iOS - UIPageControl - Disable left/right tap to decrement/increment

I have a question that I believe is a little bit weird due to the lack of information I'm finding online.
In my program, there is a UIPageViewController that is overlayed by a UIPageControl. In my UIPageViewController, each View Controller has a table inside with a number of items. With pages being the name for my UIPageControl, when I use pages.UserInteractionEnabled = false; my tap gesture taps underneath of the UIPageControl and taps one of the items in the table, pushing a new view controller for that item. I don't want that to happen, but I also don't want the typical functionality of UIPageControl, which is to scroll left or right depending on the location of the touch. I want this UIPageControl on my user interface for purely the indication of how many pages and which page is the current page.
I've tried removing any existing gesture recognizers from the pages.GestureRecognizers collection and that didn't work. I've tried setting pages.AllTouchEvents += (sender, e) => { return; } which also did nothing.
A thought: I have the UIPageControl as a view that spans the width of the view. Could I add a UIView and then add the UIPageControl as a subview of that, and then call its .SizeToFit() method?
In any case, thanks for taking a look. Any help and/or ideas are appreciated.
Please try pageControl.DefersCurrentPageDisplay = true; to achieve your effect.
When it is set True, the current page indicator will not be rendered until we set the pageControl's CurrentPage to change its selected indicator.

How to make an accordion style content holder UWP

So i am trying to make an accordion content holder for an uwp application. I can't find anything resembling what i want to achive in the documentation. Is this someting i need to build from scratch using stackpanels and codebehiend ect ect, or are there tools I can use within the libary which I havent found yet ?
Here Is an example of what i want. When the users clicks on a vaccine name, a content box containg information about that vaccine will dropdown. And if it is click while expanded, it will slide back up and only display the name again. An accordion.
Any suggestions, tutorials, articles on the subject will be much appreciated. Thanks in advance.
There is UWP Community Toolkit available that has an expander control that you may be able to utilize. You can get the code sample from the Windows Store and the source code is on github.
https://blogs.windows.com/buildingapps/2016/08/17/introducing-the-uwp-community-toolkit/#v6cSIzET7QwQOb8O.97
I believe from the answer that you know how to make a ListView using DataTemplate. If not search the documentation for this.
So I believe that the most important piece of the question is about the expanding.
First in your DataTemplate bind Height to your DataModel for example like this:
<Grid Height="{x:Bind Item.Height, Mode = OneWay}">...</Grid>
Then place Clicked (or Tapped if its control doesn't support Clicked) event on that arrow, and handle it in the code like this (Tapped may require different arguments but they'll appear automatically anyway):
Arrow_Clicked(object sender, RoutedEventArgs e)
{
var item = (sender as Button).DataSource as Item;
if (item.Height == 80)
item.Height = 200;
else
item.Height = 80;
}

How to change the background image of a button when clicked in code?

There is a similar question like mine here in Stackoverflow but it only explains how to change it in XAML. I want to know how can I change it in code.
Here is a image that shows how I do it in XAML using Blend:
Link for full size: https://snag.gy/4Skk4.jpg
Basically I want to change the background of a button's pressed state in C# but I can't seem to find any examples on the Internet. It must be in code because sometimes the image of the button will change therefore the button's pressed image must change as well.
The following code is just to change the image of the button and it's just the start.
image.ImageSource = new System.Windows.Media.Imaging.BitmapImage(new Uri(#"images/Button-warning-icon.png", UriKind.Relative));
image.Stretch = Stretch.Uniform;
buttonWarnings.Background = image;
If I understand you correctly, you are trying to change the appearance of the Button control in a "pressed" visual state.
I'm not near my dev computer to try it out, but to "unblock you" I'll give a direction.
First, as you noticed in your Blend screenshot, each visual state is represented with a Storyboard, which defines how various properties change. In your case, you're looking to change Background property.
The VisualStateGroups and their states are defined by the control. You can override them when you re-template the control. So, retemplate the button control using Blend with "Edit Template"->"Edit Copy".
Then, in code, you should be able to do the following:
1) Get visual states (this would not work unless you re-template the control, AFAIK)
var visualStateGroups = VisualStateManager.GetVisualStateGroups(buttonWarnings);
2) Get the VisualStateGroup of "CommonStates" from the visualStateGroups
collection
var commonStatesGroup = visualStateGroups.Find((g) => ((VisualStateGroup)g).Name == "CommonStates") as VisualStateGroup;
3) Get the "Pressed" VisualState:
var pressedVisualState = commonStatesGroup.Find((vs) => ((VisualState)vs).Name == "Pressed") as VisualState;
4) Change the storyboard of that state
pressedVisualState.Storyboard = newStoryboardWithCustomImageBackgroundProperty;
(Disclaimer: I'm not near in a computer to try it now - it's all in theory)
There are many examples to be found on the internet!
Take a look at some:
http://mobile.dzone.com/articles/windows-phone-buttonimage
http://loekvandenouweland.com/index.php/2011/01/windows-phone-image-button/
Actually its quite simple,
While in button pressed state....see part 3 in the image you uploaded above.
Above all the colors there is a row containing 5 icons.
Click on 4th icon.
it will show you option to choose image as background.

ASP.NET - Accessing All ImageButtons on a Page and Putting Two Images on an ImageButton

I actually have two questions:
(1) Is it possible to put another image on top of an ImageButton that already has an ImageUrl set (without changing the ImageUrl - literally just add the second image 'on top')? Even by using CSS?
(2) I have a dynamically set number of ImageButtons contained within a ListView. When a user clicks on an ImageButton, I change the .CssClass property of the one clicked in order to 'highlight' it. My question is this: whenever an ImageButton is click, I need to not only highlight it, but make sure I unhighlight all the others. However, I'm having trouble getting the others. I get the clicked ImageButton using
((ImageButton)sender).CssClass = "SelectedImageButton";
in the event handler. However, how do I get all the others so I can set their style 'back' to the unhighlighted style?
Thanks in advance for any help!
UPDATE: ANSWERED!
I've solved the issue mentioned in (2) using the following algorithm. Note, I've marked #OFConsulting's answer below as the correct answer because without his algorithm, I would have never gotten the following algorithm (which came from tweaking his algorithm slightly). Thanks #OFConsulting!
// Cast the sender to an ImageButton to have the clicked ImageButton
ImageButton clickedImageButton = sender as ImageButton;
// The ListView has ListViewDataItems and the ImageButtons are in
// THOSE children controls, thus match on the ImageButtons' Parents' IDs
Control parentControl = clickedImageButton.Parent;
List<ListViewDataItem> allOtherImageButtons = MyListView.Controls.OfType<ListViewDataItem().AsQueryable().Where(i => i.ID != clickedImageButton.Parent.ID).ToList();
// Highlight
clickedImageButton.CssClass = "HighlightedStyle";
// Unhighlight
foreach (ListViewDataItem button in allOtherImageButtons)
{
// The ImageButton is always the 2nd child control of the ListViewDataItem
ImageButton childImageButton = (ImageButton)button.Controls[1];
childImageButton.CssClass = "NoHighlightedStyle";
}
For Part (1) of that question, setting the background image within your css class might do the trick, but you never really explained why you just couldn't change the ImageUrl. You can always throw everything on an update panel if you need it to be dynamic without the hassle of a bunch of script.
Part (2) seems pretty straight forward. Just use a little bit of linq against the relevant control collection within your page.
protected void ImageButton5_Click(object sender, ImageClickEventArgs e)
{
ImageButton clickImageButton = sender as ImageButton;
// This example assumes all the image buttons have the same parent.
// Tweak as needed depending on the layout of your page
Control parentControl = clickImageButton.Parent;
List<ImageButton> allOtherImageButtons = parentControl.Controls.OfType<ImageButton>().AsQueryable().Where(i => i.ID != clickImageButton.ID).ToList();
// Highlight
clickImageButton.CssClass = "WhateverHighlights";
// Unhighlight
foreach (ImageButton button in allOtherImageButtons)
{
button.CssClass = "WhateverClears";
}
}
Edit: One more thing. Make sure any controls you are adding dynamically get added before Page_Load (I.E. during Init). There are some viewstate issues associated with adding control too late.

Make sure ListViewItem is shown in a ListView

I have a long ListView which contains a list of actions which my app is currently running (each action at a time).
Upon running each action, the relevant ListViewItem is bolded.
The ListView is long so I have vertical scroll bar.
My question is how to make the current running action shown to the user, meaning, how do I "scroll" the list view to that item.
I tried to manually select the row ==> didn't work.
I've used ListViewItem.EnsureVisible but that made the ListView flicker on each change.
Any idea? Thanks.
Edited: I've added some code, even though the code is pretty simple.
Whenever a new action is running, I run the following:
foreach (ListViewItem item in m_ListView.Items)
{
FontStyle style = ((index == value) ? FontStyle.Bold : FontStyle.Regular);
item.Font = new Font(item.Font, style);
if (index == value)
{
m_ModulesListView.EnsureVisible(index);
}
index++;
}
You means
listView1.EnsureVisible(listView1.Items.Count - 1);
Maybe you should call ListView.BeginUpdate() before your loop and ListView.EndUpdate() after your loop.
Found a nice solution.
It involves using win32 but it does the job.
Apparently, it is possible to set double buffering on the list which solves the flickering problem.
So, using EnsureVisible with the double buffering work just fine.

Categories

Resources