Home > Blockchain >  Can I store SelectedItem property value of a Picker under a ListView in an array?
Can I store SelectedItem property value of a Picker under a ListView in an array?

Time:11-07

I am working with Xamarin ListView and Picker, trying to create an android app that calculates a student's GPA in one page(view). I have a class GPADetails that takes care of the Picker properties. This class contains a "List"...

public ObservableRangeCollection<string> UnitList{get;set;}

...of units binded to the ItemSource of the Picker. it also contains a "property field"...

private string selectedUnit=null;

public string SelectedUnit { get => selectedUnit;

set => SetProperty(ref selectedUnit, value); } ...that is binded to the SelectedItem property of the picker.

The ListView is being populated by binding a "List"...

public ObservableRangeCollection<GPADetails> GPADetailsList {get;set;}
...of multiple objects of type GPADetails class to the ItemSource of the ListView.(so that the user can pick different units for different subjects) Here's the function that populates the listView

public void DisplayTemplates()

        {

            GPADetailsList.Clear();

            //Instantiates  template object equivalent to the number of courses

            for (int i = 0; i < int.Parse(NumberOfCourses); i  )

            {

                GPADetailsList.Add(

                new GPADetails

                {

                    //initializing picker properties with picker items

                    UnitList = UnitItems,                    

                    SelectedUnit = null,                    

                    TemplateID = i,

                   

                });

                

            }

        }

Heres the Xaml of the ListView and the picker... ...

<ListView x:Name="listView" ItemsSource="{Binding GPADetailsList}" SelectionMode="None" >
            <ListView.ItemTemplate>

                <DataTemplate>

                    <ViewCell>

                            <StackLayout >

                                <Editor  Placeholder="Course Code" PlaceholderColor="White"                                        HorizontalOptions="StartAndExpand">
                                </Editor>

                                <Picker x:Name="PickerUnit" Title="Pick a Unit" TitleColor="white"

                                        HorizontalOptions="EndAndExpand"
        VerticalOptions="Fill" HorizontalTextAlignment="Center"                                        VerticalTextAlignment="Center" FontSize="15"
ItemsSource="{Binding UnitList}"
SelectedItem="{Binding SelectedUnit, Mode=TwoWay }"
                                      >
                             </Picker>
                          </StackLayout>                      

                    </ViewCell>

                </DataTemplate>

            </ListView.ItemTemplate>

        </ListView>

...

Now here's where I'm having problems. Each time the user selects a unit on the page, the selectedItem property of the picker is triggered. And the SelectedUnit property of the GPADetails class detects the property changed. I want so store the SelectedItem of each Picker that is under the ListView in an array. Using a property TemplateID of class GPADetails, I'm able to track which picker has been selected. So I use TemplateID as the index of my array. But I keep having problems because my C# is weak.

I tried doing this in the SelectedUnit property in class GPADetails by using a condition in the set accessor and initializing the array at the selected index with the selectedUnit. Heres the code..

private string selectedUnit;

        public string SelectedUnit

        {

            get { return selectedUnit; }

            set

            {

                SetProperty(ref selectedUnit, value);

                if (selectedUnit != null)

                    SelectedUnitList[TemplateID] = selectedUnit;

            }

 

        }

But with that, i can only assign one value to the array, if i try to assign another, the previously assigned index goes back to the default value, null.

P.S. I don't know if I asked this right, but any help would be appreciated, thanks dev fam...

CodePudding user response:

I think you can use the properties/events to interact with the ListView instead of relying in the observable property.

You can use ItemSelected

<ListView ItemsSource="{x:Static local:interactiveListViewXaml.items}" ItemSelected="OnSelection" ItemTapped="OnTap" IsPullToRefreshEnabled="true" Refreshing="OnRefresh">

https://github.com/xamarin/xamarin-forms-samples/blob/main/UserInterface/ListView/Interactivity/interactivityListView/interactivityListView/Views/interactiveListViewXaml.xaml

About the implementation I'm not sure what TemplateID is or all this sentence I want so store the SelectedItem of each Picker under the ListView in an array using a property I don't understand it

CodePudding user response:

I delete my origin post and the following is my new answer.

In your GPADetails.cs, add a new property (relative to SelectedUnitList, I prefer to use a dict, that's SelectedUnitDict):

public Dictionary<int,string> SelectedUnitDict { get; set; }

In your GPACalculationViewmodel, also create a property (i just use the same name for convenience):

public Dictionary<int, string> SelelctedUnitDict { get; set; }

and add a new line in the DisplayTemplates methods, that makes each instance of GPADetails get the same SelectedUnitDict in GPACalculationViewmodel.

for (int i = 0; i < int.Parse(NumberOfCourses); i  )
    {

        GPADetailsList.Add(

            new GPADetails

            {

                //initializing picker properties with picker items

                UnitList = UnitItems,                    

                SelectedUnit = null,                    

                TemplateID = i,

                // Add this new line
                SelelctedUnitDict = SelelctedUnitDict

            });

Finally, in GPADetails.cs, just like your code:

public string SelectedUnit
    {
        ...
        set
        {
            ...
            if (selectedUnit != null)
            {
                
                SelectedUnitDict[TemplateID] = selectedUnit;
            }

        } 
    }

That's worked for me. I can get the selectedItem of each picker in my SelectedUnitDict in GPACalculationViewmodel. The key is TemplateID and the value is SelectedItem.

Hope my answer could help you.

  • Related