I'm about to badly embarrass my self here - being a complete newb to c# (& OO) and Xamarin.Forms (trying to learn too much in one go, I know)
I'm trying to create a stack-layout of options that will contain e.g. labels and buttons in which I want to control the Text property of the buttons when any of them are clicked.
I previously tried using databinding/itemsource on the stacklayout but got even more lost and have not been able to find examples I could make very much sense of - the documentation looks like it should be really simple, alas :-(
In the code listed below I can access both the mapOptsCntrl object and its methods as well as the stack layout control via its x:Name from the event handler methods of buttons in the XAML. But if I want to change things based on programmatically created button having been clicked I'm kinda lost.
I hope this is not too much code to post here:
`
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;
namespace AgentApp
{
public partial class zDev_Map_Options_list : ContentPage
{
public class LocOption : Object { public string AddressLine { get; set; } public string State { get; set; } } public class MapOptsCntrl : Object { public Dictionary<string, LocOption> ListOptsContainer = new Dictionary<string, LocOption>(); public void Create(int number) { for (int i = 0; i < number; i++) { string key = i.ToString(); LocOption LocOption = new LocOption { AddressLine = "Addy str " + key, State = "Show", }; ListOptsContainer.Add(key, LocOption); } } public List<StackLayout> Draw() { int optsCount = ListOptsContainer.Count(); List<StackLayout> listItems = new List<StackLayout>(); for (int i = 0; i < optsCount; i++) { string key = i.ToString(); Button listOptBtn = new Button { Text = ListOptsContainer[key].State + " " + key, }; listOptBtn.Clicked += (sender, args) => { this.Click(key); }; StackLayout listItem = new StackLayout { Orientation = StackOrientation.Horizontal, Children = { new Label { Text = "Label " + key }, listOptBtn, }, }; listItems.Add(listItem); }; return listItems; } public void Click(string key) { Console.WriteLine("Click " + key + " state is " + ListOptsContainer[key].State); int optsCount = ListOptsContainer.Count(); for (int i = 0; i < optsCount; i++) { string newState; string thisKey = i.ToString(); if (i.ToString() == key) { string curState = ListOptsContainer[key].State; newState = (curState == "Use") ? "Show" : "Use"; } else { newState = "Show"; } ListOptsContainer[thisKey].State = newState; } // how to trigger a redraw? //// to efectively do what btn_redraw_Clicked does? } } MapOptsCntrl mapOptsCntrl = new MapOptsCntrl(); public zDev_Map_Options_list() { InitializeComponent(); } private void btn_go_Clicked(object sender, EventArgs e) { mapOptsCntrl.Create(3); List<StackLayout> listItems = mapOptsCntrl.Draw(); OptionsListStack.Children.Clear(); foreach (StackLayout item in listItems) { OptionsListStack.Children.Add(item); } } private void btn_redraw_Clicked(object sender, EventArgs e) { List<StackLayout> listItems = mapOptsCntrl.Draw(); OptionsListStack.Children.Clear(); foreach (StackLayout item in listItems) { OptionsListStack.Children.Add(item); } } }
}
`
and the xaml:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="AgentApp.zDev_Map_Options_list"> <ContentPage.Content> <Grid RowDefinitions="*,*,*,5*" x:Name="mainGrid"> <Label Text="Map Options List Event Handeling" Grid.Row="0" HorizontalOptions="CenterAndExpand" /> <Button x:Name="btn_go" Text="Create" Grid.Row="1" Clicked="btn_go_Clicked"/> <Button x:Name="btn_redraw" Text="Redraw" Grid.Row="2" Clicked="btn_redraw_Clicked"/> <StackLayout x:Name="OptionsListStack" Grid.Row="3"/> </Grid> </ContentPage.Content> </ContentPage>
Thanks in advance for any direction or help!