Maximus
Maximus

Reputation: 1299

Load only selected item in a XAML FlipView

Is there a way, for the FlipView control, to ONLY have it load the selected item??

The default style of a FlipView, from Microsoft's styles, uses a VirtualizingStackPanel:

    <Setter Property="ItemsPanel">
      <Setter.Value>
        <ItemsPanelTemplate>
          <VirtualizingStackPanel AreScrollSnapPointsRegular="True" Orientation="Horizontal" />
        </ItemsPanelTemplate>
      </Setter.Value>
    </Setter>

What occurs is that the current element and adjacent elements will begin to load. What I would like for the FlipView to do is only load the item when it's shown (in other words, when it becomes the selected item).

Is that possible?

Upvotes: 0

Views: 516

Answers (3)

Martin Zikmund
Martin Zikmund

Reputation: 39072

If you have a data-bound ImageSource, you can do it in such a way, that you manually force the load of the current item when the selection of the FlipView changes.

You can create a custom item class. Note that it implements the INotifyPropertyChanged interface so that it notifies the control when the image is loaded:

public class FlipViewItemViewModel : INotifyPropertyChanged
{
    private bool _isLoaded = false;

    private ImageSource _imageSource = null;

    public ImageSource ImageSource
    {
        get
        {
            return _imageSource;
        }
        set
        {
            _imageSource = value;
            OnPropertyChanged();
        }
    }

    /// <summary>
    /// Forces the loading of the item
    /// </summary>
    public void ForceLoad()
    {
        //prevent loading twice
        if ( !_isLoaded )
        {         
            _isLoaded = true;       
            //load the image (probably from network?)
            ImageSource = new BitmapImage( 
               new Uri( "ms-appx:///Assets/StoreLogo.png" ) );
        }
    }

    /// <summary>
    /// INotifyPropertyChanged implementation
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged( 
        [CallerMemberName] string propertyName = null )
    {
        PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
    }
}

In XAML, you have to bind the data source to your FlipView using ItemsSource and handle the SelectionChanged event:

 <FlipView x:Name="FlipControl" 
           ItemsSource="{x:Bind Items}" 
           SelectionChanged="Selector_OnSelectionChanged">

Inside the SelectionChanged handler you then manually call the ForceLoad method for the current item.

private void Selector_OnSelectionChanged( object sender, SelectionChangedEventArgs e )
{
    //get the currently selected item
    var currentItem = FlipControl.SelectedItem as FlipViewItemViewModel;
    //force-load it
    currentItem?.ForceLoad();
}

I have made a GitHub sample with this solution and example.

Upvotes: 0

mjw
mjw

Reputation: 410

You could make your custom classes:

public class ImageGallery : FlipView
{
    public ImageGallery()
    {
        SelectionChanged += (s, a) =>
        {
            ((ImageItem)Items[SelectedIndex]).Load()
        }
    }
}

public class ImageItem : FlipViewItem
{
    public ImageItem(SomeType yourImageInfo)
    {
        Content = new YourControl(yourImageInfo);
    }

    public void Load()
    {
        //load your image
    }
}

Upvotes: 1

Maximus
Maximus

Reputation: 1299

Here's my problem:

I'm using a flipview which contains items that consist of a custom control that load an image asynchronously. I only want to load the image of the selected index. So when the flipview loads, the first item loads. If the user swipes left, now the second image loads, and so on.

Upvotes: 0

Related Questions