Matthew
Matthew

Reputation: 4056

how to use panorama item selectionchanged

I am attempting to detect the current panorama item that a user is currently on and then toggle an application bar icon button isenabled property accordingly. I have not had any luck on how to implement a feature like this, or properly detect the current panorama item. Specifically, I would like to use the selectedItem property and detect the name of the panorama items instead of the selectedIndex property because the panorama items may change their order. Is there any way to do this? So far what I have is the following:

MainPage.xaml

<controls:Panorama SelectionChanged="PanoramaItemSelectionChanged">         

            <!--Panorama item one-->
            <controls:PanoramaItem Header="statuses" >
                ...
            </controls:PanoramaItem>

            <!--Panorama item two-->
            <controls:PanoramaItem Header="mentions" >
                ...
            </controls:PanoramaItem>

            <!--Panorama item three-->
            <controls:PanoramaItem Header="messages" >
                ...
            </controls:PanoramaItem>

            <!--Panorama item four-->
            <controls:PanoramaItem Header="favorites" >
                ...
            </controls:PanoramaItem>

        </controls:Panorama> 

MainPage.xaml.cs

private void PanoramaItemSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        string currentPanoramaItem = e.AddedItems[0] as string;

        switch (currentPanoramaItem)
        {
            case "statuses":
                //show application bar button?
                break;
            case "mentions":
                //show application bar button?
                break;
            case "messages":
                ((ApplicationBarIconButton)ApplicationBar.Buttons[0]).IsEnabled = true;
                break;
            case "favorites":
                //show application bar button?
                break;
            default:
                return;
        }            
    }

my SelectionChanged implementation does not work for some reason. Any ideas (with an example please)?

Upvotes: 0

Views: 4991

Answers (6)

Yiannis Stavrianos
Yiannis Stavrianos

Reputation: 335

My solution is for WP8 but must be the same for WP7.x

First add a name on each PanoramaItem and use that one as a reference from your code. In my case I have x:Name = "piRegister" and x:Name = "piLogin"

On SelectionChanged event you must recreate your ApplicationBar:

private void Login_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   string piName = (e.AddedItems[0] as PanoramaItem).Name;

   switch(piName)
   {
      case "piLogin":
         SetupAppBar_Signin();
         break;
      case "piRegister":
         SetupAppBar_Register();
         break;
   }
}

//use this code only if you need to setup the app bar from code
void SetupAppBar()
{
   ApplicationBar = new ApplicationBar();

   ApplicationBar.Mode = ApplicationBarMode.Default;
   ApplicationBar.Opacity = 1.0;
   ApplicationBar.IsVisible = true;
   ApplicationBar.IsMenuEnabled = true;
}


void SetupAppBar_Signin()
{   
   ApplicationBar.Buttons.Clear();

   ApplicationBarIconButton button1 = new ApplicationBarIconButton();
   button1.IconUri = new Uri("/icon.png", UriKind.Relative);
   button1.Text = "button 1";
   ApplicationBar.Buttons.Add(button1);
   button1.Click += new EventHandler(button1_Click);
}

void SetupAppBar_Register()
{   
   ApplicationBar.Buttons.Clear();

   ApplicationBarIconButton button1 = new ApplicationBarIconButton();
   button1.IconUri = new Uri("/icon.png", UriKind.Relative);
   button1.Text = "button 1";
   ApplicationBar.Buttons.Add(button1);
   button1.Click += new EventHandler(button1_Click);

   ApplicationBarIconButton button2 = new ApplicationBarIconButton();
   button2.IconUri = new Uri("/icon.png", UriKind.Relative);
   button2.Text = "button 1";
   ApplicationBar.Buttons.Add(button2);
   button2.Click += new EventHandler(button2_Click);
}

Upvotes: 0

ADITYA BUGALIA
ADITYA BUGALIA

Reputation: 1

there is alternative to switch case.... you can use

private void PanoramaItemSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (panoramacontrol.selecteditem == xyzpanorama)
    {
        //....................//
    }
}

where

  • panoramacontrol is name of your Panorama
  • xyzpanorama is name of item in Panorama. for eg "statuses" in your case.

not to be confused with header as header and name may be different.

Upvotes: 0

garenyondem
garenyondem

Reputation: 541

You can also simply use index numbers for triggering different actions. As panorama pages are not designed for using with big numbers of PanoramaItems. It may not be a problem.

Xaml

<phone:Panorama Title="my application" SelectionChanged="Panorama_SelectionChanged">

    <phone:PanoramaItem Header="first item">
    </phone:PanoramaItem>

    <phone:PanoramaItem Header="second item">
    </phone:PanoramaItem>

    <phone:PanoramaItem Header="third item">
    </phone:PanoramaItem>

</phone:Panorama>

I assume you are working with a ApplicationBar visibility

Code

private void Panorama_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    switch (((Panorama)sender).SelectedIndex)
    {

        case 0: // defines the first PanoramaItem
            ApplicationBar.IsVisible = true;
            break;

        case 1: // second one
            ApplicationBar.IsVisible = false;
            break;

        case 2: // third one
            ApplicationBar.IsVisible = true;
            break;
    }
}

Upvotes: 1

Carlos P
Carlos P

Reputation: 3988

Testing using the header name is a bad idea, since your code will break if you rename your panorama item headers, or localize them.

You could work out the selected index, but that would break if you re-ordered your items:

        PanoramaItem selectedItem = (PanoramaItem)e.AddedItems[0];
        int selectedIndex = mainPanorama.Items.IndexOf(selectedItem);

The most robust way would be to set a Tag on your Panorama Items and test for that:

XAML:

   <phone:Panorama x:Name="myPanorama" SelectionChanged="Panorama_SelectionChanged_1">

        <phone:PanoramaItem Header="the places" Tag="places">
        </phone:PanoramaItem>

        <phone:PanoramaItem Header="the routes" Tag="routes">
        </phone:PanoramaItem>
    </phone:Panorama>

Code behind:

    private void Panorama_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count < 1) return;
        if (!(e.AddedItems[0] is PanoramaItem)) return;

        PanoramaItem selectedItem = (PanoramaItem)e.AddedItems[0];

        string strTag = (string)selectedItem.Tag;
        if (strTag.Equals("places"))
            // Do places stuff
        else if (strTag.Equals("routes"))
            // Do routes stuff

     }

Upvotes: 1

Matthew
Matthew

Reputation: 4056

The panoramaItemSelectionChanged string value used in the switch statement should be the following:

string currentPanoramaItem = ((PanoramaItem)(((Panorama)sender).SelectedItem)).Header.ToString();

Upvotes: 0

Rich Hopkins
Rich Hopkins

Reputation: 1891

The way I'd do it is to name the panorama, then you can refer to its selectedIndex property to determine which panorama item is selected. I believe that would be more efficient than dealing with strings that are in the headers.

    <Controls:Panorama name="x">...</Controls:Panorama>

    private void PanoramaItemSelectionChanged(object sender, SelectionChangedEventArgs e)    
 { switch (x.SelectedIndex) ... }

I would also add though, that it is not a best practice to use the application bar in a panorama, in fact it is recommended that you not do so, but whether you do or not is really up to you.

Upvotes: 0

Related Questions