Forum Xamarin.Forms

Open picker on Listview itemtapped event in xamarin forms

VIVEKNEGIVIVEKNEGI USMember ✭✭✭

I want to Open picker list (picker.focus()) whenever I click on Frame.
I am using Xamarin forms with Prism Framework.

I have tried with below code but getting item object , not picker object.
<ListView.Behaviors>

                        <behavior:EventToCommandBehavior
                            EventName="ItemTapped"
                            Command="{Binding ApplyLeaveInfoCommand}"

                            EventArgsParameterPath="Item"/>

                    </ListView.Behaviors>

So Can I get picker.focus() after click on listview Item ???

Complete code:-


<ListView.ItemTemplate>





<Grid.RowDefinitions>


</Grid.RowDefinitions>
<Grid.ColumnDefinitions>


</Grid.ColumnDefinitions>

                                            <Image Source="{Binding ImageSource}" Aspect="AspectFit" Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" VerticalOptions="CenterAndExpand" />
                                        </Grid><Frame.GestureRecognizers>
                                            <ClickGestureRecognizer Command="{Binding ApplyLeaveInfoCommand}"
                                                                    CommandParameter="{Binding .}"
                                                                    /></Frame.GestureRecognizers>
                        </Frame>
            </StackLayout>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>

Answers

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    Add a tap gesture recognizer to Frame and get the frame's content in Tapped event. Iterate the content to get the Picker and call Picker.Focus command.

    private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
    {
        Frame frame = sender as Frame;
        Grid grid = (Grid)frame.Content;
    
        foreach (var item in grid.Children)
        {
            if (item.GetType() == typeof(Picker))
            {
                Picker picker = item as Picker;
                picker.Focus();
                return;
            }
        }
    }
    
  • VIVEKNEGIVIVEKNEGI USMember ✭✭✭
    edited December 2019

    I already did but nothing happened...

    """"""<Frame.GestureRecognizers>

    </Frame.GestureRecognizers>"""""""""

  • VIVEKNEGIVIVEKNEGI USMember ✭✭✭

    I already did but nothing happened...
    <Frame.GestureRecognizers>

    </Frame.GestureRecognizers>

  • VIVEKNEGIVIVEKNEGI USMember ✭✭✭

    I already did but nothing happened...
    "<Frame.GestureRecognizers></Frame.GestureRecognizers>"

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    I created a basic sample to test the code and it works well.

    Here is the demo file you can test on your side.

  • VIVEKNEGIVIVEKNEGI USMember ✭✭✭



    <CollectionView.ItemsLayout>

    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>




    <Grid.RowDefinitions>


    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>



                                        </Grid.ColumnDefinitions>
                                        <Label Text="{Binding LeaveSummaryTitle}" HorizontalTextAlignment="Start" FontSize="{DynamicResource FontSize3}" TextColor="{DynamicResource ColorInteraction1Base}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" />
                                        <Label Text="{Binding LeaveCount}" HorizontalTextAlignment="Start" FontSize="{DynamicResource FontSize10}" TextColor="{DynamicResource ColorInkBase}" Grid.Row="1" Grid.Column="0" />
                                        <BoxView Grid.Row="1" Grid.Column="1" BackgroundColor="{DynamicResource ColorInkBase}" />
                                        <Label Text="{Binding LeaveDate}" HorizontalTextAlignment="Start" FontSize="{DynamicResource FontSize3}" TextColor="{DynamicResource ColorInkBase}" Grid.Row="1" Grid.Column="2" />
                                        <Image x:Name="image" Margin="0,4" Aspect="AspectFit" HeightRequest="24" WidthRequest="24" Source="icon_info" Grid.Row="1" Grid.Column="3" effects:TooltipEffect.Position="Top" effects:TooltipEffect.BackgroundColor="Navy" effects:TooltipEffect.Text="{Binding ToolTipText}" effects:TooltipEffect.HasTooltip="True" >
    
    
    
                                            </Image>
    
    
    
    
                                    </Grid>
    
    
                                    <Frame.GestureRecognizers>
    
                                                <TapGestureRecognizer Command="{Binding InfoCommand}" CommandParameter="{x:Reference frame}"/>
    
    
                                            </Frame.GestureRecognizers>
    
                                </Frame>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </StackLayout>
    

    ViewModel =>

    public DelegateCommand InfoCommand { get; set; }
    private ObservableCollection _leaveSummaryList;

    public TestingCollectionViewClickViewModel(INavigationService navigationService, IPageDialogService pageDialogService)
    {
    this._navigationService = navigationService;
    this._pageDialogService = pageDialogService;
    InfoCommand = new DelegateCommand(ShowInfo);
    SetLeaveSummaryList();
    }

    public ObservableCollection LeaveSummaryList { get => _leaveSummaryList; set => SetProperty(ref _leaveSummaryList, value); }

        private void ShowInfo(Frame obj)
        {
            var value = obj;
    
        }
    
        private void SetLeaveSummaryList()
        {
            LeaveSummaryList = new ObservableCollection<LeaveSummary>();
        // able to add items to list.
        }
    

    }

    so according to above code, it should call ShowInfo method but its not calling . Using prism framework with Xamarin forms

  • YelinzhYelinzh Member, Xamarin Team Xamurai
    edited December 2019

    Use Tapped event instead of a command because it's needed to get the item's Picker to call the Focus method which cannot be implemented in the model class.

  • VIVEKNEGIVIVEKNEGI USMember ✭✭✭

    @Jarvan You code is working while you are clicking on picker itself. if you click outside that it won't work. Please debug the application you will get the actual call that its not calling when you are clicking on the frame

  • YelinzhYelinzh Member, Xamarin Team Xamurai
    edited December 2019

    @VIVEKNEGI said:
    @Jarvan You code is working while you are clicking on picker itself. if you click outside that it won't work. Please debug the application you will get the actual call that its not calling when you are clicking on the frame

    Please download the demo and test it on your side. The picker could be opened when clicking
    the frame.

  • VIVEKNEGIVIVEKNEGI USMember ✭✭✭

    (" <Frame.GestureRecognizers>

                                            </Frame.GestureRecognizers>")
    

    @Jarvan thank you so much for your help, from above code i am able to call the method as well as get the instance of an image. But its working only on collectionview not inside listview..now I am trying the same behavior to be achieve inside listview...

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    Use MVVM pattern to set the data binding, add the Command in Model class. Check the code:
    page.xaml

    <ContentPage.BindingContext>
        <local:_ViewModel/>
    </ContentPage.BindingContext>
    
    <ContentPage.Content>
        <StackLayout>
            <ListView x:Name="listview" HasUnevenRows="True" ItemsSource="{Binding Models}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout>.
                                <Frame>
                                    <Frame.GestureRecognizers>
                                        <TapGestureRecognizer Command="{Binding TapCommand}" CommandParameter="command" />
                                    </Frame.GestureRecognizers>
                                    ...
                                </Frame>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
    

    Model Class

    public class _Model
    {
        public string content { set; get; }
    
        ICommand tapCommand;
        public ICommand TapCommand
        {
            get { return tapCommand; }
        }
    
        public _Model()
        {
            tapCommand = new Command(OnTapped);
        }
    
        void OnTapped(object s)
        {
            Console.WriteLine("==tap gesture");
        }
    }
    

    ViewModel Class

    public class _ViewModel : INotifyPropertyChanged
    {
        public List<_Model> Models { get; set; }
    
        public _ViewModel()
        {
            Models = new List<_Model>();
            for (int i = 0; i < 10; i++)
            {
                Models.Add(new _Model { content = "content_" + i });
            }
        }
    
        #region INotifyPropertyChanged 
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
    
  • PatrickLongPatrickLong USMember ✭✭

    Persevere with this post. It is messy and hard to read but it does have the answer.
    Essentially you need to do the following:

    Add a Tapped GestureRecogniser in your ItemTemplate. The eventhandler will appear in the code file for the page
    Add this code to the _Tapped handler

    Grid grid = sender as Grid;
    
    foreach (var item in grid.Children)
    {
        if (item.GetType() == typeof(CustomPicker))
        {
            CustomPicker picker = item as CustomPicker;
            picker.Focus();
            return;
        }
    }
    

    The "grid" variable is whatever element you have attached the Gesture Recogniser to

    Thanks @jarvan and @VIVEKNEGI

Sign In or Register to comment.