So I have to make my layout for the first time in C#...
Now I want to be able to tab on a listview item and then go to a detail page with the data of te tapped item.. How can I do this?
I currently have this code;
public MainPage()
{
GeneratePage();
InitializeComponent();
}
private async Task GeneratePage()
{
List<Folder> folders = await ApiManager.GetFoldersAsync();
foreach (var f in folders)
{
List<Lists> lists = new List<Lists>();
foreach (int id in f.list_ids)
{
lists.Add(await ApiManager.GetSpecificListAsync(id));
// Debug.WriteLine("ID for list '"+ f.title +"' : " + id);
}
this.Children.Add(new ContentPage
{
Title = f.title,
Content = new ListView
{
ItemsSource = lists
}
});
}
}
Normally I use XAML instead of CodeBehind to create UIs, but the following snippet should do the trick, but I have not tested it.
Just attach to the ItemTapped event. Alternatively you could also add an TapGestureRecognizer onto your ListView.
private async Task GeneratePage()
{
List<Folder> folders = await ApiManager.GetFoldersAsync();
foreach (var f in folders)
{
List<Lists> lists = new List<Lists>();
foreach (int id in f.list_ids)
{
lists.Add(await ApiManager.GetSpecificListAsync(id));
// Debug.WriteLine("ID for list '"+ f.title +"' : " + id);
}
ListView listView = new ListView { ItemsSource = lists };
listView.ItemTapped += ListViewOnItemTapped;
this.Children.Add(new ContentPage
{
Title = f.title,
Content = listView
});
}
}
void ListViewOnItemTapped(object sender, ItemTappedEventArgs itemTappedEventArgs)
{
throw new NotImplementedException();
}
you have a list of ContentPage?? It's very strange. But, normally, for add a tap-event for a ListView item you subscribe to the ItemTapped event.
var list = new ListView();
list.ItemsSource = myItems;
list.ItemTapped += myEventTapped();
Content = list;`
Related
I am working on a Xamarin.Android proyect, I am filling a list view with a Web Service query. Now I need to access the listview's items values which I will use for future queries.
This is how I fill my listView
WebReference.ToDoWS cliente = new ToDoWS();
DataTable tabla = new DataTable();
tabla = cliente.ObtenerTareas();
ListView listado = FindViewById<ListView>(Resource.Id.tareas);
if (tabla.Rows.Count > 0)
{
List<string> tareas = new List<string>();
for (int i = 0; i < tabla.Rows.Count; i++)
{
tareas.Add(tabla.Rows[i][1].ToString());
}
ArrayAdapter<string> adaptador = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, tareas);
listado.Adapter = adaptador;
}
Here's a pick of how it looks
Is there a way to access the text values inside each row? I tried with the SetOnClickListener but I don't know how to use it at all.
I was able to access the item index with the following:
listado.ItemClick += (sender, e) =>
{
string index = e.Position.ToString();
Toast.MakeText(this, "Click" + index, ToastLength.Long).Show();
};
Documentation Referece: https://learn.microsoft.com/en-us/xamarin/android/internals/api-design#Events_and_Listeners
I'm using Live Charts in my application for a pareto chart. I have made a SeriesCollection. I'm loading it from a Stored Procedure in the following way:
public void LoadChart()
{
List<DataTops> dataTops = GetTops();
ChartValues<int> Pareto = new ChartValues<int>();
List<string> timevalues = new List<string>();
int selected = ComboSelect();
IDLables = new List<string>();
foreach (var item in dataTops)
{
values.Add(item.Total);
Pareto.Add(item.Running);
IDLables.Add((item.W) + "." + (item.B));
}
TopAlarms = new SeriesCollection
{
new ColumnSeries
{
Title = "Total",
Values =values,
DataLabels = false,
ScalesYAt = 0,
},
new LineSeries
{
Title = "%",
Values = Pareto,
ScalesYAt = 1,
PointGeometrySize = 0
}
};
public List<DataTops> GetTops()
{
int selected = ComboSelect();
DataSet Ds = new DataSet();
DataSetTableAdapters.TimePerID_TopTableAdapter TimerTopta = new DataSetTableAdapters.TimePerID_TopTableAdapter();
TimerTopta.Fill(Ds.TimePerID_Top, selected);
List<DataTops> Tops = new List<DataTops>();
foreach (DataRow row in Ds.Tables["TimePerID_Top"].Rows)
{
Tops.Add(new DataTops() { Total = (int)row["Total"], W = (int)row["W"], B = (int)row["B"], Amount = (int)row["Amount"], Running = (int)row["Running"] });
}
return Tops;
}
I have a combobox to select an amount to show (selected in the dataset) and a button that I use to update the chart. The Chart works fine, but whenever I press the update button it only adds new data behind the already existing data.
Live charts doesn't automatically clear the chart collection data upon loading so I did this:
private void UpdateChart_Click(object sender, RoutedEventArgs e)
{
if (TopAlarms != null)
{
TopAlarms.Clear();
}
LoadChart();
}
But it still won't clear and reload the chart. How can i reload the chart when the button is pressed so the new selected data amount will show?
after some testing and reasearch I have the following solution for clearing the chart:
try
{
if (TopAlarms != null)
{
TopAlarms.Clear();
}
}
catch { }
This is probably not the best solution but it works for me.
I am trying to get the data from my SQLite table into a List<string> and then into an ArrayAdapter<string> and into a ListView.
How would I get the data pulled from the below code, into a ListView using an ArrayAdapter?
DB Helper.cs:
public List<string> getNoteList()
{
List<string> noteList = new List<string>();
SQLiteDatabase db = this.ReadableDatabase;
ICursor cursor = db.Query(DB_TABLE, new string[] { DB_COLUMN}, null, null, null, null, null);
while (cursor.MoveToNext())
{
int index = cursor.GetColumnIndex(DB_COLUMN);
noteList.Add(cursor.GetString(index));
}
return noteList;
}
As you can see it is put into noteList, but how would I code an array adapter so that the noteList goes into a ListView?
UPDATE 1: MainActivity.cs
public void LoadNoteList()
{
List<string> noteList = dbHelper.getNoteList();
adapter = new ArrayAdapter<string>(this, Resource.Layout.list_black_text, noteList);
lvNotes.Adapter = adapter;
}
Error:
Change noteList's type to ArrayList and add follow line at the place after your ListView being initialization
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, noteList);
listview.setAdapter(adapter);
try this
here cards is my linked-list
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_single_choice);
for (MerchantCard card : cards) {
arrayAdapter.add(card.getName());
}
ListView listView = (ListView) mView.findViewById(R.id.listView);
listView.setAdapter(arrayAdapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedCardTypeId = cards.get(position).getId();
Log.d("request", cards.get(position).getId() + " " + cards.get(position).getName());
}
});
Method for sending data to the web service
async void getData(string center)
{
string url = "http://10.91.91.50:7500/NNRAService/webresources/NNRA/getMedicalFilter?centerName="+center;
HttpClient client = new HttpClient();
//string response = await client.GetStringAsync(url);
//var data = JsonConvert.DeserializeObject(response);
//tbOutputText.Text = data.centerName.ToString();
//tbOutputText.Text= data.ToString();
HttpResponseMessage response = await client.GetAsync(new Uri(url));
var jsonString = await response.Content.ReadAsStringAsync();
JsonArray root = JsonValue.Parse(jsonString).GetArray();
verifyList.Clear();
for (uint i = 0; i < root.Count; i++)
{
string CenterName = root.GetObjectAt(i).GetNamedString("centerName");
string Address = root.GetObjectAt(i).GetNamedString("address");
string status = root.GetObjectAt(i).GetNamedNumber("isActive").ToString();
if(status=="1")
{
active = "SAFE";
}
var verified = new Class4
{
centerName = CenterName,
address = Address,
isActive = active,
};
verifyList.Add(verified);
};
verifyListView.ItemsSource = verifyList;
}
When I call the method, I want it to work in such a way that when I change the text in the textbox and I click the button, it should generate another list for me on the list view
private void btnVerify_Click(object sender, RoutedEventArgs e)
{
vtext = vCenter.Text;
if(vtext != null)
{
getData(vtext);
}
}
Do you use the List to save the Class4 Collections? If so, please set the null to ItemsSource of the ListView before you set the List to the ItemsSource of the ListView.
I suggest you use the ObservableCollection. It represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
For example:
private ObservableCollection<Class4> Items;
public MainPage()
{
this.InitializeComponent();
Items = new ObservableCollection<Class4>();
verifyListView.ItemsSource = Items;
}
By the way, if we have set the ObservableCollection to the
ItemsSource of the ListView once, we do not need to set it anymore.
Xamarin Help .
Can't Get selected value for spinner in my custom listview adapter.
MyListViewAdapter.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
namespace Kites
{
public class AttendenceViewAdapter : BaseAdapter<string>
{
private List<string> mstudents;
private Context mcontext;
public AttendenceViewAdapter(Context context, List<string> stud)
{
mstudents = stud;
mcontext = context;
}
public override int Count
{
get
{
return mstudents.Count;
}
}
public override long GetItemId (int position)
{
return position;
}
public override string this[int position]
{
get
{
return mstudents [position].ToString();
}
}
public override View GetView (int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null) // otherwise create a new one
view = LayoutInflater.From(mcontext).Inflate(Resource.Layout.listview_attendence , null, false);
// set view properties to reflect data for the given row
TextView txtStudent = view.FindViewById<TextView>(Resource.Id.textStudentNameTeacherAttendence);
txtStudent.Text = mstudents[position];
Spinner spinner = view.FindViewById<Spinner> (Resource.Id.spinnerTeacherAttendence);
var adapter = ArrayAdapter.CreateFromResource (mcontext, Resource.Array.attendence_array, Android.Resource.Layout.SimpleDropDownItem1Line);
adapter.SetDropDownViewResource (Android.Resource.Layout.SimpleSpinnerDropDownItem);
spinner.Focusable = false;
spinner.FocusableInTouchMode = false;
spinner.Clickable = true;
spinner.ItemSelected += Spinner_ItemSelected;
spinner.Adapter = adapter;
var abcde = spinner.SelectedItemPosition;
spinner.SetSelection (abcde);
// return the view, populated with data, for display
return view;
}
void Spinner_ItemSelected (object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner spinner = (Spinner)sender;
var abc = spinner.SelectedItemPosition;
spinner.RequestFocusFromTouch ();
spinner.SetSelection (abc);
}
}
}
Main Activity.cs
ListView lsStu = FindViewById<ListView> (Resource.Id.listStudentAttendence);
AttendenceViewAdapter adapter = new AttendenceViewAdapter (this, mstudents);
lsStu.Adapter = adapter;
for(int i = 0; i < abc; i++)
{
View view = adapter.GetView(i, null, null);
TextView txtStudentName = view.FindViewById<TextView> (Resource.Id.textStudentNameTeacherAttendence);
string txtSN = txtStudentName.Text;
Spinner spinner = view.FindViewById<Spinner> (Resource.Id.spinnerTeacherAttendence);
var txtS = spinner.SelectedItem;
// I Cant Get The Selected Value Here. , I Am Getting the default Value not the selected value .do i do that
string studentattendence = "insert into student_attendence values ('" + txtClassID.Text + "','" + txtClassName.Text + "','" + txtDate.Text + "','" + txtSN + "','" + txtS + "');";
SqlCommand abcdedh = new SqlCommand (studentattendence, con);
abcdedh.ExecuteNonQuery ();
Toast.MakeText (this, "Attendence Saved", ToastLength.Short).Show();
}
I get the default value at position 0 but not the value which i have selected.
when i place a breakpoint in mylistviewadapter i get the selected value position every time i select a new value but i am not getting it in the main activity please help me.
The problem is: You call adapter.GetView(i, null, null); So the second parameter convertView is null which means, that you will inflate a new view.
This approach fails, because GetView is not meant to be called outside from the ListView or the view that is using the adapter. The second reason why this will fail is the mechanism called view reuse. If you have 100 items in your list there will be much less views created (only as much as can be shown son screen simultaneously plus a few more for smooth scrolling).
The approach you should use is:
Create a class Attendence, that contains the Name and all other values that you need.
public class Attendence
{
public string ClassId { get; set; }
public string ClassName { get; set; }
public string StudentName { get; set; }
public string Attendence { get; set; }
//TODO: maybe some more
}
Inherit from BaseAdapter<Attendence>
If the values in your list item changes, write them back to the current student (e.g. in your Spinner_ItemSelected).
public class AttendenceViewAdapter : BaseAdapter<Attendence>
{
private List<Attendence> mstudents;
private Context mcontext;
public AttendenceViewAdapter(Context context, List<Attendence> stud)
{
mstudents = stud;
mcontext = context;
}
// ...
public override View GetView (int position, View convertView, ViewGroup parent)
{
View view = convertView;
Spinner spinner;
if (view == null){
view = LayoutInflater.From(mcontext).Inflate(Resource.Layout.listview_attendence , null, false);
spinner = view.FindViewById<Spinner> (Resource.Id.spinnerTeacherAttendence);
var adapter = ArrayAdapter.CreateFromResource (mcontext, Resource.Array.attendence_array, Android.Resource.Layout.SimpleDropDownItem1Line);
adapter.SetDropDownViewResource (Android.Resource.Layout.SimpleSpinnerDropDownItem);
spinner.Focusable = false;
spinner.FocusableInTouchMode = false;
spinner.Clickable = true;
spinner.ItemSelected += Spinner_ItemSelected;
spinner.Adapter = adapter;
}
else {
spinner = view.FindViewById<Spinner> (Resource.Id.spinnerTeacherAttendence);
}
// set view properties to reflect data for the given row
TextView txtStudent = view.FindViewById<TextView>(Resource.Id.textStudentNameTeacherAttendence);
txtStudent.Text = mstudents[position].StudentName;
// TODO: use mstudents[position].Attendence here
var abcde = spinner.SelectedItemPosition;
spinner.SetSelection(abcde);
spinner.Tag = position; // use this to know which student has been edited
// return the view, populated with data, for display
return view;
}
void Spinner_ItemSelected (object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner spinner = (Spinner)sender;
var abc = spinner.SelectedItemPosition;
var position = (int)spinner.Tag;
spinner.RequestFocusFromTouch ();
spinner.SetSelection (abc);
mstudents[position].Attendence = //TODO: selected value of the spinner;
}
}
In your MainActivity you can iterate over the list of students, not over the views of the list.
// given: students is your list of Attendence
foreach(Attendence attendence in students)
{
string studentattendence = "insert into student_attendence values ('" + attendence.ClassId + "','" + attendence.ClassName + "','" + txtDate.Text + "','" + txtSN + "','" + attendence.Attendence + "');";
SqlCommand abcdedh = new SqlCommand (studentattendence, con);
abcdedh.ExecuteNonQuery ();
Toast.MakeText (this, "Attendence Saved", ToastLength.Short).Show();
}