Xamarin Picker elemek nem frissülnek

Címkék
Xamarin Picker elemek nem frissülnek
2022-11-07T13:38:33+01:00
2022-11-09T13:26:22+01:00
2022-11-09T14:19:43+01:00
kokohun
Sziasztok!

Adott két darab Picker-em Xamarin alatt. És azt szeretném megcsinálni hogy a második Picker az elsőtől függően változzon. Pl. Van egy Bakancsom, annak a méretei számokban értendőek 35-45-ig pl. Van egy Kesztyűm, annak a méretei pedig XS-től XL-ig értendőek pl. Azt szeretném ha a Bakancsot választom ki, a következő legördülő menüből 35-45-ig lehessen választani, ha megváltoztatom a Bakancsot Kesztyűre, akkor XS-től XL-ig. A méretek mindkét esetben egy List-be kerülnek eltárolásra az adatbázisból (ToolsSizesList), ezt Debug-al ki is írattam, frissül a List ahogy kell, azonban a felületen nem változik a 2. Picker tartalma. 

XAML:

<Picker x:Name="toolsSelectorPicker" Title="Munkavédelmi eszköz" SelectedIndexChanged="selectTool" ></Picker> <Picker x:Name="toolsSizeSelectorPicker" Title="Méret" SelectedIndexChanged="selectSize" ></Picker>


XAML.CS:

public void selectTool(object sender, EventArgs e) { string selectedToolName = ""; newCardboardModel.SafetyTool.ClearProps(); newCardboardModel.ToolsSizesList.Clear(); string selectedToolName = toolsSelectorPicker.SelectedItem as String; newCardboardModel.SafetyTool.ToolName = String.Concat(selectedToolName.ToString().Where(c => !Char.IsWhiteSpace(c))); toolsSizeSelector(); toolsColorSelector(); } public void selectSize(object sender, EventArgs e) { toolsSizeSelectorPicker.ItemsSource = newCardboardModel.ToolsSizesList; for (int i = 0; i < newCardboardModel.ToolsSizesList.Count; i++) { Debug.WriteLine(newCardboardModel.ToolsSizesList); } string selectedSize = toolsSizeSelectorPicker.SelectedItem as String; newCardboardModel.SafetyTool.Size = String.Concat(selectedSize.ToString().Where(c => !Char.IsWhiteSpace(c))); }



public void toolsSelector(SqlConnection con)

{

 SqlCommand cmd = new SqlCommand("SELECT * FROM SafetyToolsNames", con);

DataTable dt = new DataTable();

con.Close();

con.Open();

 dt.Load(cmd.ExecuteReader());

con.Close();



var toolsList = new List<string>();

 for (int i = 0; i < dt.Rows.Count; i++)

{

toolsList.Add(dt.Rows["Name"].ToString());

}

toolsSelectorPicker.ItemsSource = toolsList;

}



public void toolsSizeSelector()

{

SqlCommand cmd = new SqlCommand("SELECT * FROM SafetyToolsNames WHERE Name = '" + newCardboardModel.SafetyTool.ToolName + "'", con);

DataTable dt = new DataTable();

con.Close();

con.Open(); 



dt.Load(cmd.ExecuteReader());

con.Close();


SqlCommand cmd2 = new SqlCommand("SELECT * FROM SafetyToolsSizes WHERE ToolID = '" + dt.Rows[0]["ID"].ToString() + "'", con);

DataTable dt2 = new DataTable();

con.Close();

con.Open();

dt2.Load(cmd2.ExecuteReader());

con.Close();

 for (int i = 0; i < dt2.Rows.Count; i++)

{

              newCardboardModel.ToolsSizesList.Add(dt2.Rows["Size"].ToString());

 }


toolsSizeSelectorPicker.ItemsSource = newCardboardModel.ToolsSizesList;

}
VIEWMODEL.CS

List<string> toolsSizeslist = new List<string>(); public List<string> ToolsSizesList { get => toolsSizeslist; set { toolsSizeslist = value; var args = new PropertyChangedEventArgs(nameof(ToolsSizesList)); PropertyChanged?.Invoke(this, args); } }

Válaszokat előre is köszönöm!
Mutasd a teljes hozzászólást!
Frissítéskor az sql lekérdezésed eredményét állítsd össze egy List-ben, ahogy korábban, majd a listát a következő módon add értékül az ObservableCollection-nak:

ToolsSizesList = new ObservableCollection<string>(sizeList);
Így mindig csak a lekérdezés eredménye lesz benne.
Mutasd a teljes hozzászólást!

  • Tedd ObservableCollection-be a List helyett.
    Mutasd a teljes hozzászólást!
  • XAML-ben adatkötéssel (binding) kapcsold a listádat a pickerhez:

    ItemsSource="{Binding ToolsSizesList}"
    Így, ha változik a lista, akkor az automatikusan változik a controlban is. Gondolom a page-edhez be van állítva a viewmodelled, mint DataContext.

    Az ilyen bind-olt listákat én ObservableCollection-ként szoktam deklarálni:

    public ObservableCollection<string> ToolsSizesList
    Itt olvashatsz erről bővebben, példával illusztrálva, az idevágó Microsoft doksiban:
    Setting a Picker's ItemsSource Property - Xamarin
    Mutasd a teljes hozzászólást!
  • Köszönöm, ez így működik. Jelenleg azonban az előző méret típusokat is listázza, nyilván mivel nincs ürítve a ObservableCollection. Nem tudom mikor kellene üríteni, a SelectTool metódusomban tűnik logikusnak az elején, akkor viszont az első kiválasztásnál jó, a 2. kiválasztásnál a következő hibát kapom:

    System.NullReferenceException: 'Object reference not set to an instance of an object.' selectedSize was null.
    Ez esetben mikor kellene ürítenem a Collectiont hogy megfelelően működjön?
    Mutasd a teljes hozzászólást!
  • Frissítéskor az sql lekérdezésed eredményét állítsd össze egy List-ben, ahogy korábban, majd a listát a következő módon add értékül az ObservableCollection-nak:

    ToolsSizesList = new ObservableCollection<string>(sizeList);
    Így mindig csak a lekérdezés eredménye lesz benne.
    Mutasd a teljes hozzászólást!
  • Ezt megtettem ha így gondoltad. Azonban továbbra is fennáll a következő hibám:

    System.NullReferenceException: 'Object reference not set to an instance of an object.' selectedSize was null.
    (83. sor) a selectedSize-ra ha 2x-ra választanék az első Picker-ből. Mi lehet a gondja? Olyan mintha megzavarodna a SelectedItem property.

    Szerk.: Ha XAML-ben ott a Pickeren az ItemsSource akkor sincs változás.
    Mutasd a teljes hozzászólást!
  • Úgy néz ki megoldódott. A XAML-ben írtam be a SafetyTool.Size Property-t SelectedItem Binding-al, a XAML.CS-ből pedig kivettem a selectSize metódust ahogy van és így kiválóan működik. Mondjuk érdekes egy megoldás hogy XAML.CS-ben nem működik egy az egyben ugyanaz ami XAML-ben meg igen.
    Mutasd a teljes hozzászólást!
Címkék
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd