Search code examples
c#xamarinpicker

How to populate a picker depending on a choice from another picker?


My problem is that I've got a picker and it is not populating when I choose an option on another picker. I have looked at multiple solutions but non is working.

XAML:

            <Picker x:Name="customerPicker" 
                    Title="Customer" 
                    ItemsSource="{Binding CustomerSource}"
                    SelectedItem="{Binding SelectedCustomer}" 
                    Grid.Row="0" Grid.Column="1" />
            <Picker x:Name="salerOrderPicker"  
                    Title="Sales Order" 
                    ItemsSource="{Binding BuildSalesOrderSource}"
                    SelectedItem="{Binding SelectedSalesOrder}"
                    Grid.Row="0" Grid.Column="1" />

This is my XAML code for my Pickers. The first picker is populating.

ViewModel Code:

public List<string> CustomerSource { get; set; }
public List<string> BuildSalesOrderSource { get; set; }

Declaring my Lists for the pickers

private void GetSQLBuildCustomer()
        {
            try
            {
                var customerList = new List<string>();
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    connection.Open();

                    using (SqlCommand command = new SqlCommand("SELECT CardCode, CardName FROM OCRD WHERE CardCode LIKE " +
                        "'FOR001' OR CardCode LIKE '115638'", connection))
                    {
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            if (reader != null)
                            {
                                while (reader.Read())
                                {
                                    if (reader["CardName"] != DBNull.Value)
                                    {
                                        customerList.Add(new Item(reader.GetString(0), reader.GetString(1)).ToString());
                                    }
                                }
                                CustomerSource = customerList;
                                //Application.Current.MainPage.BindingContext = CustomerSource;
                            }
                        }
                    }
                    connection.Close();
                }
            }
            catch (Exception ex)
            {
                Application.Current.MainPage.DisplayAlert("Alert", "Error Customer Selection lists :" + ex.Message, "OK");
            }
        }

This is to populate the first picker. This piece of code works and populates the picker

    public string selectedCustomer;
    public string SelectedCustomer
    {
        get { return selectedCustomer; }
        set
        {
            selectedCustomer = value;
            OnPropertyChanged("SelectedCustomer");
         
            if (selectedCustomer != null)
            {
                GetSQLBuildSalesOrders(selectedCustomer);
                Static_Var.Changed = true;
            }
        }
    }

This is when I select an option in the first picker and is working

    private void GetSQLBuildSalesOrders(string sCustomer)
    {
        
        try
        {
            var salesOrderList = new List<string>();
            salesOrderList.Clear();
            string Customer = string.Empty;

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();

                if (selectedCustomer != "")
                {
                    string[] CustomerName = selectedCustomer.Split(':');
                    Customer = CustomerName[0];
                }

                string SQL = "";
                if (Customer.ToUpper().Contains("FOR001"))
                {
                    SQL = "SELECT TOP 1 DocNum, O.[DocEntry],R.[DocEntry], R.Dscription FROM [ORDR] O " +
                       "INNER JOIN RDR1 R ON O.DocEntry = R.DocEntry " +
                       "WHERE [CardCode] = '" + Customer + "' AND [DocStatus] = 'O'";
                        //" AND Cast(O.DocDate as date) = Cast(Getdate() as Date)";
                }
                else
                {
                    SQL = "SELECT TOP 5 DocNum, O.[DocEntry],R.[DocEntry], R.Dscription FROM [ORDR] O " +
                      "INNER JOIN RDR1 R ON O.DocEntry = R.DocEntry " +
                      "WHERE [CardCode] = '" + Customer + "' AND [DocStatus] = 'O'";
                }

                using (SqlCommand command = new SqlCommand(SQL, connection))
                {
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                salesOrderList.Add(reader.GetInt32(0).ToString() + " : " + reader.GetString(3));
                                DocEntrySelected = reader.GetInt32(1);
                            }
                            BuildSalesOrderSource = salesOrderList;
                            //Application.Current.MainPage.BindingContext = BuildSalesOrderSource;
                        }
                    }
                }
                connection.Close();
            }
           //BuildSalesOrderSource.Add(" ");
        }
        catch (Exception ex)
        {
            Application.Current.MainPage.DisplayAlert("Alert", "Error Creating Orders Selection lists for selected Customer: "
                + ex.Message, "OK");
        }
    }

This is the second picker which is not updating it populate the list but does not display anything.

Thanks for your help.


Solution

  • Please change the type of the BuildSalesOrderSource from List<string> to ObservableCollection<string>.

    In other words, you can replace the following code:

    public List<string> BuildSalesOrderSource { get; set; }
    

    with code:

    public ObservableCollection<string> BuildSalesOrderSource { get; set; } = new ObservableCollection<string>();