Matthew Pans
Matthew Pans

Reputation: 869

How can I initially show the Swipeview programmatically using Listview?

In my Xamarin Forms project, I have a listview. In that listview, I'm using a swipeview to display the options when an item gets swiped. As the users are unaware that they need to swipe an item to view the options, I need to show the listview's first item to get swiped automatically, show the options for a few seconds, and close automatically when the page gets opened. How can I apply it to the listview item? Please suggest a solution.

Code:

<ListView>   
<ListView.ItemTemplate>
    <DataTemplate>
        <ViewCell>
            <SwipeView>
                <SwipeView.RightItems>
                    <SwipeItems>
                        <SwipeItemView>
                            <StackLayout
                                Orientation="Horizontal"
                                WidthRequest="150">
                                <Image 
                                    Source="ic_delete_orange_xx.png">
                                </Image>
                            </StackLayout>                                    
                        </SwipeItemView>
                    </SwipeItems>
                </SwipeView.RightItems>
                <!-- Listview Content -->                                
            </SwipeView>
        </ViewCell>
    </DataTemplate>
</ListView.ItemTemplate>
</ListView>

Upvotes: 0

Views: 582

Answers (3)

Igor Krupskiy
Igor Krupskiy

Reputation: 31

small addition. A very useful technique, in my opinion, for demonstrating to the user the non-obvious functionality of the application.

You may experience the following error CS0618

replace

Device.StartTimer(TimeSpan.FromSeconds(1), TimerElapsed) ;

with

IDispatcherTimer timer;
timer = Dispatcher.CreateTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += (sender, e) => TimerElapsed();
timer.Start();

Upvotes: 0

Liqun Shen-MSFT
Liqun Shen-MSFT

Reputation: 8290

I share a workaround here. Since you cannot access the control in Template, you could use a Xamarin.Forms Bindable Properties. I write a demo below and you could have a look.

First, I define a custom control, let's call it CustomSwipeView which inherits SwipeView. In CustomSwipeView, we define a BindableProperty OpenFlag which controls the state of swipeView (open or close).

public class CustomSwipeView : SwipeView
{
    public static readonly BindableProperty OpenFlagProperty =
BindableProperty.Create("OpenFlag", typeof(bool), typeof(CustomSwipeView), null, propertyChanged:OnPropertyChanged);

    private static void OnPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var flag = (bool)newValue;
        SwipeView m = bindable as SwipeView;
        
        if(m != null)
        {
            if (flag)
            {
                m.Open(OpenSwipeItem.RightItems);
            }
            else
            {
                m.Close();
            }
        }
    }

    public bool OpenFlag
    {
        get { return (bool)GetValue(OpenFlagProperty); }
        set { SetValue(OpenFlagProperty, value); }
    }
}

This is xaml file which consumes the custom SwipeView :

<ListView ItemsSource="{Binding ItemCollection}" x:Name="mylist">
<ListView.ItemTemplate>
    <DataTemplate>
        <ViewCell>
            <local:CustomSwipeView x:Name="myview" OpenFlag="{Binding OpenFlag}" >
                <SwipeView.RightItems>
                ...
                </SwipeView.RightItems>
            ...
            </local:CustomSwipeView>

In ViewModel, we define the data collection for ItemsSource of ListView.

public ObservableCollection<Item> ItemCollection { get; set; } = new ObservableCollection<Item>();

this is for Model Item Class:

public class Item : INotifyPropertyChanged
{

    private bool openFlag;
    public bool OpenFlag
    {
        get
        {
            return openFlag;

        }

        set
        {
            openFlag = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OpenFlag)));
        }

    }
    public string MyTitle { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

And in code behind, I define a Timer. After one second, the swipeView of first item will close.

public partial class MainPage : ContentPage
{
    MainPageViewModel viewModel;
    public MainPage()
    {
        InitializeComponent();
        viewModel = new MainPageViewModel();
        BindingContext = viewModel;    
    }

    protected override async void OnAppearing()
    { 
        base.OnAppearing();
        await Task.Delay(10); // delay some time to let it initially open
        viewModel.ItemCollection[0].OpenFlag = true;
        Device.StartTimer(TimeSpan.FromSeconds(1), TimerElapsed) ;
    }

    private bool TimerElapsed()
    {
        viewModel.ItemCollection[0].OpenFlag = false;
        return false;
    }
}

enter image description here

Hope it works! If you have any questions, free to ask me.

Upvotes: 1

Guangyu Bai - MSFT
Guangyu Bai - MSFT

Reputation: 4606

You can create a CollectionView and put the SwipeView inside.

Here is the sample:

<CollectionView ItemsSource="{Binding MyItems}">
         <CollectionView.ItemTemplate>
                 <DataTemplate>
                        <SwipeView>
                            <SwipeView.RightItems>
                                <SwipeItems>
                                    <SwipeItem Text="Click here" BackgroundColor="Green" Invoked="SwipeItem_Invoked" />
                                </SwipeItems>
                            </SwipeView.RightItems>

                            //You can put the data you want to show in the layout.
                            <StackLayout>
                                <Label BackgroundColor="White" Text="{Binding .}" FontSize="Title" Padding="30,10,30,10"/>
                            </StackLayout>
                        </SwipeView>
                 </DataTemplate>
         </CollectionView.ItemTemplate>
  </CollectionView>

Given a SwipeView named swipeView, the following example shows how to open a SwipeView to reveal the swipe items in the LeftItems collection:

swipeView.Open(OpenSwipeItem.LeftItems);

Upvotes: 0

Related Questions