El0din
El0din

Reputation: 3370

UWP PivotItem Header visibility binding

I'm doing a binding in UWP, the listview is not showing(so it's working fine), but the header is still on the view.

So the problem is that the header is not getting the binding from the PivotItem, what can be the problem?

<PivotItem Header="Hello" Visibility="{Binding isVisible, Converter={StaticResource Visibility}}">
    <ListView ItemsSource="{Binding myList}"/>
</PivotItem>

Upvotes: 0

Views: 731

Answers (1)

Martin Zikmund
Martin Zikmund

Reputation: 39082

This is actually a bit tricky. Setting Visibility on a PivotItem does indeed hide only the contents of the item, not the PivotItem itself. That said, you can hide it from the code-behind by removing it from the pivot completely:

MyPivot.Items.Remove(HideablePivotItem);

The problem is now the fact that you need to trigger it on binding change. For that purpose I suggest you use a custom Behavior and a CallMethodAction.

First install the Microsoft.Xaml.Behaviors.Uwp.Managed from NuGet (right-click your project, click Manage NuGet Packages... find the package using search and click Install.

Now, create a new class DataChangeTriggerBehavior class:

public class DataChangeTriggerBehavior : Trigger<FrameworkElement>
{
    public static readonly DependencyProperty BindingProperty = DependencyProperty.Register(
        nameof(Binding), typeof(object), typeof(DataChangeTriggerBehavior), new PropertyMetadata(null, BindingChanged));

    public object Binding
    {
        get => (object)GetValue(BindingProperty);
        set => SetValue(BindingProperty, value);
    }

    private static void BindingChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
    {
        DataChangeTriggerBehavior changeTrigger = (DataChangeTriggerBehavior)dependencyObject;

        if (changeTrigger.AssociatedObject == null) return;

        Interaction.ExecuteActions(changeTrigger.AssociatedObject, changeTrigger.Actions, args);
    }
}

This behavior will observe a binding and trigger its associated actions whenever the binding changes.

Now, update your Page element as follows:

<Page 
    ...
    x:Name="Page"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    xmlns:customBehavior="using:XXX"
    mc:Ignorable="d">

Where XXX is the namespace where your behavior is defined.

Now use the behavior in your Pivot:

<Pivot x:Name="MyPivot">
    <interactivity:Interaction.Behaviors>
        <local:DataChangeTriggerBehavior Binding="{Binding isVisible}">
            <core:CallMethodAction MethodName="TogglePivotItem" 
                                   TargetObject="{Binding ElementName=Page}" />
        </local:DataChangeTriggerBehavior>
    </interactivity:Interaction.Behaviors>
    <PivotItem Header="Hello" Visibility="Collapsed" x:Name="HideablePivotItem">
        <ListView ItemsSource="{Binding myList}"/>
    </PivotItem>
</Pivot>

Finally you must define the TogglePivotItem method in your page's code-behind:

private int originalPosition = 0;

public void TogglePivotItem()
{
    if (MyPivot.Items.Contains(HideablePivotItem))
    {
        //store the position of the item to be readded later
        originalPosition = MyPivot.Items.IndexOf(HideablePivotItem);
        MyPivot.Items.Remove(HideablePivotItem);
    }
    else
    {
        MyPivot.Items.Insert(originalPosition, HideablePivotItem);
    }            
}

I am storing the original position of the PivotItem so that it can be re-added to the same place again.

Upvotes: 2

Related Questions