16

I have a Page with an Pivot-control and in some cases I don't want to show a particular PivotItem.
Setting the Visibility to collapsed doesn't seem to affect it at all.

Any suggestions?

Stefan Wick MSFT
  • 13,600
  • 1
  • 32
  • 51
Jimmy Engtröm
  • 1,998
  • 4
  • 23
  • 34

8 Answers8

14

you should be able to remove or add PivotItems dynamically in your Pivot by using the respective collection methods on Pivot.Items .

Let me know if this doesn't work for your scenario.

btlog
  • 4,760
  • 2
  • 29
  • 38
Stefan Wick MSFT
  • 13,600
  • 1
  • 32
  • 51
  • 2
    Worked great thanks I used the following code: NameOfPivotControl.Items.Remove(NameOfPivotControl.Items.Single(p => ((PivotItem)p).Name == "NameOfPivotItem")); – Jimmy Engtröm Apr 03 '11 at 21:48
  • 1
    It doesn't work for pivot items with complex header(i mean when u use control template for pivot item). Repro: http://db.tt/PHVUHzQl – Grigory Oct 03 '11 at 09:47
  • 1
    That is why you give each PivotItem a x:Name that is unique. Then if you have a pivot item set to x:Name="RemoveMe" you can go NameOfPivotControl.Items.Remove(RemoveMe); and be done with it. – Mitchell Skurnik Nov 05 '11 at 05:55
  • NameOfPivotControl.Items.Remove(NameOfPivotControl.Items.Single(p => ((PivotItem)p).Name == "NameOfPivotItem")); this code good. but, i am tried to delete one more pivot coming error. tell me some idea to solve the problem. – Jeeva Nov 14 '11 at 07:58
12

I've created a custom behavior for showing/hiding pivot item

Usage:

< i:Interaction.Behaviors>
    < common:HideablePivotItemBehavior Visible="{Binding variable}" />
</ i:Interaction.Behaviors >

Code:

/// <summary>
/// Behavior which enables showing/hiding of a pivot item`
/// </summary>
public class HideablePivotItemBehavior : Behavior<PivotItem>
{
    #region Static Fields

    public static readonly DependencyProperty VisibleProperty = DependencyProperty.Register(
        "Visible",
        typeof(bool),
        typeof(HideablePivotItemBehavior),
        new PropertyMetadata(true, VisiblePropertyChanged));

    #endregion

    #region Fields

    private Pivot _parentPivot;

    private PivotItem _pivotItem;

    private int _previousPivotItemIndex;

    private int _lastPivotItemsCount;

    #endregion

    #region Public Properties

    public bool Visible
    {
        get
        {
            return (bool)this.GetValue(VisibleProperty);
        }

        set
        {
            this.SetValue(VisibleProperty, value);
        }
    }

    #endregion

    #region Methods

    protected override void OnAttached()
    {
        base.OnAttached();

        this._pivotItem = AssociatedObject;
    }

    private static void VisiblePropertyChanged(DependencyObject dpObj, DependencyPropertyChangedEventArgs change)
    {
        if (change.NewValue.GetType() != typeof(bool) || dpObj.GetType() != typeof(HideablePivotItemBehavior))
        {
            return;
        }

        var behavior = (HideablePivotItemBehavior)dpObj;
        var pivotItem = behavior._pivotItem;

        // Parent pivot has to be assigned after the visual tree is initialized
        if (behavior._parentPivot == null)
        {
            behavior._parentPivot = (Pivot)behavior._pivotItem.Parent;
            // if the parent is null return
            if (behavior._parentPivot == null)
            {
                return;
            }
        }

        var parentPivot = behavior._parentPivot;
        if (!(bool)change.NewValue)
        {
            if (parentPivot.Items.Contains(behavior._pivotItem))
            {
                behavior._previousPivotItemIndex = parentPivot.Items.IndexOf(pivotItem);
                parentPivot.Items.Remove(pivotItem);
                behavior._lastPivotItemsCount = parentPivot.Items.Count;
            }
        }
        else
        {
            if (!parentPivot.Items.Contains(pivotItem))
            {
                if (behavior._lastPivotItemsCount >= parentPivot.Items.Count)
                {

                    parentPivot.Items.Insert(behavior._previousPivotItemIndex, pivotItem);
                }
                else
                {
                    parentPivot.Items.Add(pivotItem);
                }
            }
        }
    }
    #endregion
}
Bajena
  • 181
  • 2
  • 9
7

You can remove the pivot item from the parent pivot control

parentPivotControl.Items.Remove(pivotItemToBeRemoved);
Udo Held
  • 12,314
  • 11
  • 67
  • 93
Sudhir Mann
  • 71
  • 1
  • 1
1

Removing PivotItems is easy, but if you want to put them back afterwards I've found that the headers get messed up and start overlapping each other. This also happens if you set the Visibility of a header to Collapsed and then later make it Visible again.

So I solved my particular problem by setting the opacity of each unwanted PivotItem (and its header) to 0.

              PivotItem p = (PivotItem)MainPivot.Items.ToList()[indexToHide];
              p.Opacity = 0;
              ((UIElement)p.Header).Opacity = 0;

However, this leaves gaps where the missing PivotItems are.

For me, the gaps were not a problem because I only want to remove items at the end of my PivotItemList, so I get some whitespace between the last and first PivotItems. The problem was, I was still able to swipe to a hidden PivotItem. In order to fix this, I overrode Pivot.SelectionChanged() so that whenever the user swipes to a hidden PivotItem, the code moves on to the next item instead. I had to use a DispatchTimer from within SelectionChanged() and actually move to the next PivotItem from the DispatchTimer callback, since you have to be in the UI thread to change PivotItem.SelectedIndex.

    private void MainPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        t.Stop();   //t is my DispatchTimer, set to 100ms

        if (MainPivot.SelectedIndex >= mFirstHiddenPivotItemIndex)
        {
            //move to the first or last PivotItem, depending on the current index
            if (mCurrentSelectedPivotItemIndex == 0)
                mPivotItemToMoveTo = mFirstHiddenPivotItemIndex - 1;
            else 
                mPivotItemToMoveTo = 0;

            t.Start();
        }
        mCurrentSelectedPivotItemIndex = MainPivot.SelectedIndex;
    }

  private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        MainPivot.SelectedIndex = mPivotItemToMoveTo;
        t.Stop();
    }
dmc
  • 336
  • 3
  • 5
  • I know this is an old thread but...couldn't you just use Dispatcher.BeginInvoke() instead of the timer? – jharr100 Jul 04 '14 at 06:02
  • Yup! Thanks, I was new to WP when I posted my answer. Using BeginInvoke is much better. – dmc Sep 23 '14 at 22:58
0
foreach (PivotItem item in MyPivot.Items.ToList())
{
    if (item.Visibility == Visibility.Collapsed)
        MyPivot.Items.Remove(item);
}
Jami
  • 161
  • 1
  • 4
0

Setting IsLocked property to true will make all other Pivot items to disappear except the current pivot item. But this will not hide one particular pivot item of our choice.

CRUSADER
  • 5,486
  • 3
  • 28
  • 64
0

To elaborate on the solution of adding/removing pivotItems, rather than hiding them.

Let's say we want the pivotItem to be initially invisible, and appear only on a certain event.

mainPivot.Items.Remove(someTab);

Then to add it again,

 if (!mainPivot.Items.Cast<PivotItem>().Any(p => p.Name == "someTab"))
 {
      mainPivot.Items.Insert(1,someTab);
  }  

I've used Insert rather than add to control the position where the tab appears. You have to ensure you don't add the same tab twice, which is the reason for the if statement.

Fiach Reid
  • 6,149
  • 2
  • 30
  • 34
0

I've modified the Bajena behavior to improve it, solving the issue with losing the original position of the PivotItem when showing/hiding repeteadly and the issue when parentpivot control is null (not initialized yet).

Notice that this behavior must be attached to the Pivot, not to the PivotItem.

Code:

  public class PivotItemHideableBehavior : Behavior<Pivot>
  {
    private Dictionary<PivotItem, int> DictionaryIndexes { get; set; }

    public static readonly DependencyProperty VisibleProperty = DependencyProperty.Register(
        "Visible",
        typeof(bool),
        typeof(PivotItemHideableBehavior),
        new PropertyMetadata(true, VisiblePropertyChanged));

    public static readonly DependencyProperty PivotItemProperty = DependencyProperty.Register(
        "PivotItem",
        typeof(PivotItem),
        typeof(PivotItemHideableBehavior),
        new PropertyMetadata(null));

    public bool Visible
    {
      get { return (bool)GetValue(VisibleProperty); }
      set { SetValue(VisibleProperty, value); }
    }

    public PivotItem PivotItem
    {
      get { return (PivotItem)GetValue(PivotItemProperty); }
      set { SetValue(PivotItemProperty, value); }
    }

    protected override void OnAttached()
    {
      base.OnAttached();
      AssociatedObject.Loaded += AssociatedObject_Loaded;
    }

    protected override void OnDetaching()
    {
      base.OnDetaching();
      AssociatedObject.Loaded -= AssociatedObject_Loaded;
    }

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
      DictionaryIndexes = new Dictionary<PivotItem, int>();
      int index = 0;
      foreach (PivotItem item in AssociatedObject.Items)
        DictionaryIndexes.Add(item, index++);
    }

    private static void VisiblePropertyChanged(DependencyObject dpObj, DependencyPropertyChangedEventArgs change)
    {
      var behavior = (PivotItemHideableBehavior)dpObj;
      var pivot = behavior.AssociatedObject;
      if (!behavior.Visible)
      {
        if (pivot.Items.Contains(behavior.PivotItem))
          pivot.Items.Remove(behavior.PivotItem);
      }
      else if (!pivot.Items.Contains(behavior.PivotItem))
      {
        int index = 0;
        foreach (var item in behavior.DictionaryIndexes)
        {
          if (item.Key == behavior.PivotItem)
            pivot.Items.Insert(index, behavior.PivotItem);
          else if (pivot.Items.Contains(item.Key))
            index++;
        }
      }
    }
  }

 

Usage:

  <Interactivity:Interaction.Behaviors>
    <Behaviors:PivotItemHideableBehavior PivotItem="{x:Bind PivotItemName}" Visible="{Binding IsPivotItemVisible}" />
  </Interactivity:Interaction.Behaviors>
Asier Peña
  • 378
  • 3
  • 12