Switch inside listview get listview item on toggle

JoReJoRe USMember

I currently have a listview which displays a list of "ConfigurationItem" objects. Each row displays a "ConfigurationItem"'s Name and Status properties in a label and has a Switch hooked up to It's Checked property value.

When I toggle a switch for a listview item I want to get the "ConfigurationItem" for that corresponds with that switch and the value of the switch so I can change the Checked property value for the "ConfigurationItem". Currenlty I've added an eventhandler for the Toggled event which receives the switch as sender but I can't figure out how I can get the "ConfigurationItem" object that corresponds with the toggled switch. Can someone please explain how I can achieve this?

XAML
<ListView x:Name="ConfigurationItemListView" BackgroundColor="Transparent"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout Orientation="Horizontal"> <StackLayout Orientation="Vertical"> <Label Text="{Binding Name}" TextColor="#fff" HorizontalOptions="FillAndExpand" FontAttributes="Bold"/> <Label Text="{Binding Status}" HorizontalOptions="FillAndExpand" TextColor="#fff" FontSize="Micro"/> </StackLayout> <Switch IsToggled="{Binding Checked}" HorizontalOptions="EndAndExpand" Toggled="OnItemToggled"/> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>

C#
private Room currentRoom { get; set; } public ConfigurationItemPage() { InitializeComponent(); }

//Room selected public ConfigurationItemPage(Room room) { InitializeComponent(); currentRoom = room; this.Title = currentRoom.Name; GetConfigurationItems(); MessagingCenter.Subscribe<ConfigurationItemDetailsPage>(this, "GetConfigurationItems", (sender) => GetConfigurationItems()); ConfigurationItemListView.ItemSelected += OnItemSelected; }

async void OnItemSelected(object sender, SelectedItemChangedEventArgs e) { if (ConfigurationItemListView.SelectedItem != null) { await Navigation.PushModalAsync(new ConfigurationItemDetailsPage((ConfigurationItem)e.SelectedItem)); } ((ListView)sender).SelectedItem = null; }

public void OnItemToggled(object sender, ToggledEventArgs e) { //Get ConfigurationItem (listview item) //save switch value Switch toggledSwitch = (Switch)sender; }

public async void GetConfigurationItems() { LoadingActivityIndicator.IsRunning = true; LoadingActivityIndicator.IsVisible = true; ConfigurationItemService configurationItemService = new ConfigurationItemService(); IEnumerable<ConfigurationItem> configurationItems = await configurationItemService.GetByRoomId(currentRoom.Id); ConfigurationItemListView.ItemsSource = configurationItems; LoadingActivityIndicator.IsRunning = false; LoadingActivityIndicator.IsVisible = false; }

Best Answer

Answers

  • JoReJoRe USMember

    Anyone?

  • JoReJoRe USMember

    @GeraldVersluis said:
    You could use Behaviors to transform your Events into behaviors. Then you can use Commands and more importantly the CommandParameter with which you can specify the object that it is about.

    Another way is to inherit from the Switch object and give it an extra property which, in your case, would be of the ConfigurationItem type. Then you can bind to that and you know which object is switched.

    Last and most ugly, you could catch the sender (like you're doing now) and traverse through its parents to find out which is the data-bound object.

    Thank you for your response, I'm trying to implement your second suggestion but I can't seem to figure out how I can bind the ConfigurationItem to the custom switch I've created.

    XAML
    <ListView x:Name="ConfigurationItemListView" BackgroundColor="Transparent" > <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout Orientation="Horizontal"> <StackLayout Orientation="Vertical"> <Label Text="{Binding Name}" TextColor="#fff" HorizontalOptions="FillAndExpand" FontAttributes="Bold"/> <Label Text="{Binding Status}" HorizontalOptions="FillAndExpand" TextColor="#fff" FontSize="Micro"/> </StackLayout> <local:ListSwitch IsToggled="{Binding Checked}" HorizontalOptions="EndAndExpand" Toggled="OnItemToggled" ConfigurationItem="{Binding ConfigurationItem}" /> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>

    C#
    public class ListSwitch: Switch { public static readonly BindableProperty ConfigurationItemProperty = BindableProperty.Create( propertyName: "ConfigurationItem", returnType: typeof(ConfigurationItem), declaringType: typeof(ListSwitch), defaultValue: null); public ConfigurationItem ConfigurationItem { get { return (ConfigurationItem)GetValue(ConfigurationItemProperty); } set { SetValue(ConfigurationItemProperty, value); } } }

    When I toggle the switch the ConfigurationItemProperty is null.

  • GeraldVersluisGeraldVersluis NLUniversity ✭✭✭✭

    Try {Binding .} for your ConfigurationItem attribute

  • JoReJoRe USMember

    @GeraldVersluis said:
    Try {Binding .} for your ConfigurationItem attribute

    That did the trick! Thanks!

  • roxanabeloiuroxanabeloiu ROMember ✭✭

    I have a similar situation, having s switch in a Model that is bind to a listviewItem. When I switch an item, I want to have my SelectedItemModel from the list. Any MVVM sample?

  • MANOJJENAMANOJJENA USMember

    @JoRe said:

    @GeraldVersluis said:
    Try {Binding .} for your ConfigurationItem attribute

    That did the trick! Thanks!

    Hi JoRe,

    I have a similar kind of requirement , to fetch the label associated with the Switch. When I am using the above solution , I am getting error
    The type or namespace for name 'ConfigurationItem' could not be found. Can you please guide. Please send the required files @ [email protected]

    Thanks,
    MJ

  • MANOJJENAMANOJJENA USMember

    Please help..
    Thanks,
    Manoj

  • IeuanWalkerIeuanWalker USMember ✭✭

    Hi, I'm trying to use this method to get an item switch (toggle event) in a listview using the command and commandParemeter, but I keep hitting the Command == null in the OnEvent Method.

    Xaml =

    <Switch IsToggled="{Binding Enabled}">
        <Switch.Behaviors>
            <Behavior:EventToCommandBehavior EventName="Toggled" Command="{Binding DisableCommand}" CommandParameter="{Binding .}"></Behavior:EventToCommandBehavior>
        </Switch.Behaviors>
    </Switch>
    

    ViewModel =

    public Command DisableCommand => new Command (async x => await DisableReminder((WasteCalenderRemindersTimeDatabaseModel)x));

    private async Task DisableReminder(WasteCalenderRemindersTimeDatabaseModel x)
    {
        await Application.Current.MainPage.DisplayAlert("Disable Reminder", $"Property: {x.PropertyAddress}, DaysBefore: {x.DaysBefore}, Time: {x.Time}", "OK");
    }
    
  • 1xo21xo2 NZMember ✭✭
            private void Switch_Toggled(object sender, ToggledEventArgs e)
            {
                ViewCell cell = (sender as Switch).Parent.Parent as ViewCell;
    
                int Id = ((M.PeriodicNotifications_M)cell.BindingContext).ID ;
    
Sign In or Register to comment.