multi select list view

8 posts, 0 answers
  1. Cédric
    Cédric avatar
    5 posts
    Member since:
    Jul 2018

    Posted 16 Jul 2018 Link to this post

    Hello,

     

    I have two Control Template in listView (SelectionMode Multiple)
    It's possible change control template on click ? 
    My problem is that it only changes the first one I select.

    C#(Selector)

    namespace ProtoDesign.Selector
    {
        public class VenteBoxOptionSelector : DataTemplateSelector
        {
            public DataTemplate TemplateDefault { get; set; }
            public DataTemplate TemplateClicked { get; set; }
     
            protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
            {
                if (item != null && (Vente)item != null)
                    return ((Vente)item).IsSelected ? TemplateClicked : TemplateDefault;
                return TemplateClicked;
            }
        }
    }

     

    XAML

    <telerikDataControls:RadListView Grid.Column="0" BackgroundColor="{StaticResource WhiteColor}" x:Name="rlv1" SelectionChanged="listView_SelectionChanged" SelectionMode="Multiple">
        <telerikDataControls:RadListView.ItemTemplateSelector>
            <Selector:VenteBoxOptionSelector>
                <Selector:VenteBoxOptionSelector.TemplateDefault>
                    <DataTemplate>
                        <telerikListView:ListViewTemplateCell>
                            <telerikListView:ListViewTemplateCell.View>
                                <StackLayout  Orientation="Horizontal">
                                    <Label Margin="10" Text="{Binding TxtLabel}" />
                                    <Label Margin="10" Text="{Binding IsSelected,Mode=TwoWay}" />
                                    <Label Margin="10" Text="Texte séparé grace au StackLayout" />
                                </StackLayout>
                            </telerikListView:ListViewTemplateCell.View>
                        </telerikListView:ListViewTemplateCell>
                    </DataTemplate>
                </Selector:VenteBoxOptionSelector.TemplateDefault>
                <Selector:VenteBoxOptionSelector.TemplateClicked>
                    <DataTemplate>
                        <telerikListView:ListViewTemplateCell>
                            <telerikListView:ListViewTemplateCell.View>
                                <StackLayout  Orientation="Horizontal">
                                    <Label Margin="10" Text="{Binding TxtLabel}" />
                                    <Label Margin="10" Text="{Binding IsSelected,Mode=TwoWay}" />
                                    <Label Margin="10" Text="Essai en cliquant" />
                                </StackLayout>
                            </telerikListView:ListViewTemplateCell.View>
                        </telerikListView:ListViewTemplateCell>
                    </DataTemplate>
                </Selector:VenteBoxOptionSelector.TemplateClicked>
            </Selector:VenteBoxOptionSelector>
        </telerikDataControls:RadListView.ItemTemplateSelector>
    </telerikDataControls:RadListView >


    XAML.CS

    private void listView_SelectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
            {
     
                if ((sender as RadListView).SelectedItems != null && (sender as RadListView).SelectedItems.Count() > 0)
                    ((sender as RadListView).SelectedItem as Vente).IsSelected = true;
           }


  2. Lance | Manager Technical Support
    Admin
    Lance | Manager Technical Support avatar
    1185 posts

    Posted 16 Jul 2018 Link to this post

    Hi Cédric,

    Can you please also share the Vente class (and any base class)? I need to make sure the model is using PropertyChanged effectively. Although the item's value was updated, unless property changed is invoked, none of the binds will be aware of the change.

    Thank you.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Cédric
    Cédric avatar
    5 posts
    Member since:
    Jul 2018

    Posted 16 Jul 2018 in reply to Lance | Manager Technical Support Link to this post

    Yes, 

    Thank You

    public class Vente
    {
       
     
        private int keyVente;
        public virtual int KeyVente
        {
            get
            {
                return this.keyVente;
            }
            set
            {
                if ((this.keyVente != value))
                {
                    this.keyVente = value;
                }
            }
        }
     
        private String txtLabel;
        public virtual String TxtLabel
        {
            get
            {
                return this.txtLabel;
            }
            set
            {
                if ((this.txtLabel != value))
                {
                    this.txtLabel = value;
                }
            }
        }
     
        private bool isSelected;
        public virtual bool IsSelected
        {
            get
            {
                return this.isSelected;
            }
            set
            {
                if ((this.isSelected != value))
                {
                    this.isSelected = value;
     
                }
            }
        }
    }
  4. Lance | Manager Technical Support
    Admin
    Lance | Manager Technical Support avatar
    1185 posts

    Posted 16 Jul 2018 Link to this post

    Hi Cédric,

    Thank you for the prompt response with the model's code.  Indeed, the IsSelected property isn't invoking OnPropertyChanged.

    Here's an updated version you can try:

    public class Vente : INotifyPropertyChanged
    {
        private int keyVente;
        public virtual int KeyVente
        {
            get => keyVente;
            set
            {
                if (keyVente == value)
                    return;
     
                keyVente = value;
                OnPropertyChanged();
            }
        }
     
        private string txtLabel;
        public virtual string TxtLabel
        {
            get => txtLabel;
            set
            {
                if (txtLabel == value)
                    return;
     
                txtLabel = value;
                OnPropertyChanged();
            }
        }
     
        private bool isSelected;
        public virtual bool IsSelected
        {
            get => isSelected;
            set
            {
                if (isSelected == value)
                    return;
     
                isSelected = value;
                OnPropertyChanged();
            }
        }
     
        public event PropertyChangedEventHandler PropertyChanged;
         
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    Let me know how it goes.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  5. Cédric
    Cédric avatar
    5 posts
    Member since:
    Jul 2018

    Posted 17 Jul 2018 in reply to Lance | Manager Technical Support Link to this post

    I tried and my problem is not solved.

    Only the first (0) SelectedItem remains true, not the others

    if ((sender as RadListView).SelectedItems != null && (sender as RadListView).SelectedItems.Count() > 0)
                  ((sender as RadListView).SelectedItem as Vente).IsSelected = true;

    Thank for help

  6. Cédric
    Cédric avatar
    5 posts
    Member since:
    Jul 2018

    Posted 17 Jul 2018 Link to this post

    Edit :
    My problem is on each click on RadListView : 
    (sender as RadListView).SelectedItem is ALWAYS (sender as RadListView).SelectedItems[0]
    And this never change     
  7. Lance | Manager Technical Support
    Admin
    Lance | Manager Technical Support avatar
    1185 posts

    Posted 17 Jul 2018 Link to this post

    Hi Cédric,

    This is expected because SelectedItem will be the first item in SelectedItems. When using MultipleSelection, you should only use the SelectedItems collection. Let me provide two options you can move forward with.


    SelectionChanged

    I recommend using the NotifyCollectionChangedArgs (e.g. NewItems, OldItems) instead of manually going through the sender and working with the RadListView directly. It is possible to take the approach you had, but you also have to worry about what items to deselect.

    Instead, take advantage of the event args. I've attached a demo for you. For your convenience, here is the relevant code:

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
     
            rlv1.ItemsSource = new ObservableCollection<Vente>(Enumerable.Range(1, 20).Select(i => new Vente {KeyVente = i, TxtLabel = $"Item {i}"}));
        }
     
        private void listView_SelectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
    // If selections were added, iterate over the newly added items and set IsSelected=true
                    foreach (Vente item in e.NewItems) item.IsSelected = true;
                    break;
                case NotifyCollectionChangedAction.Remove:
    // If the event fired because items were removed, iterate over them and set IsSelected to false
                    foreach (Vente item in e.OldItems) item.IsSelected = false;
                    break;
            }
        }
    }


    <ContentPage ... >
     
        <Grid>
            <telerikDataControls:RadListView x:Name="rlv1" SelectionChanged="listView_SelectionChanged" SelectionMode="Multiple">
                <telerikDataControls:RadListView.ItemTemplateSelector>
                    <local:VenteBoxOptionSelector>
                        <local:VenteBoxOptionSelector.TemplateDefault>
                            <DataTemplate>
                                <listView:ListViewTemplateCell>
                                    <StackLayout  Orientation="Horizontal">
                                        <Label Margin="10" Text="{Binding TxtLabel}" />
                                        <Label Margin="10" Text="{Binding IsSelected}" />
                                        <Label Margin="10" Text="Texte séparé grace au StackLayout" />
                                    </StackLayout>
                                </listView:ListViewTemplateCell>
                            </DataTemplate>
                        </local:VenteBoxOptionSelector.TemplateDefault>
                        <local:VenteBoxOptionSelector.TemplateClicked>
                            <DataTemplate>
                                <listView:ListViewTemplateCell>
                                    <StackLayout  Orientation="Horizontal">
                                        <Label Margin="10" Text="{Binding TxtLabel}" />
                                        <Label Margin="10" Text="{Binding IsSelected}" />
                                        <Label Margin="10" Text="Essai en cliquant" />
                                    </StackLayout>
                                </listView:ListViewTemplateCell>
                            </DataTemplate>
                        </local:VenteBoxOptionSelector.TemplateClicked>
                    </local:VenteBoxOptionSelector>
                </telerikDataControls:RadListView.ItemTemplateSelector>
            </telerikDataControls:RadListView >
        </Grid>
    </ContentPage>

    Here is the result ta runtime







    ItemTapped

    If you want to keep using use your current approach, I recommend switching to the ItemTapped event instead, but still use the event args instead of the sender:

    <telerikDataControls:RadListView  ItemTapped="listView__OnItemTapped" ... />


    private void listView__OnItemTapped(object sender, ItemTapEventArgs e)
    {
        if (e.Item is Vente item)
            item.IsSelected = !item.IsSelected;
    }


    Other Observations

    Another thing I noticed while building the demo, You have TwoWay binding set up for the Label property that shows the value of IsSelected. This would attempt to set the value of IsSelected with an empty string. Remove the TwoWay binding.




    I hope this helps!

    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  8. Cédric
    Cédric avatar
    5 posts
    Member since:
    Jul 2018

    Posted 17 Jul 2018 in reply to Lance | Manager Technical Support Link to this post

    Thank you very much, problem solved
Back to Top