Hello I have the following code
public class MainActivity : Activity
{
Button b;
Button c;
TextView t;
List<string> tasks = new List<string>();
ListView lView;
ArrayAdapter<string> adapter;
int count = 0;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
b = FindViewById<Button>(Resource.Id.btn);
c = FindViewById<Button>(Resource.Id.clearBtn);
t = FindViewById<TextView>(Resource.Id.tView);
lView = FindViewById<ListView>(Resource.Id.listView);
adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1,tasks);
lView.Adapter = adapter;
b.Click += ChangeTextAndAdd;
}
}
private void ChangeTextAndAdd(object sender, EventArgs e)
{
t.Text = "text is changed";
string listItem = string.Format("task{0}", count++);
tasks.Add(listItem);
adapter.NotifyDataSetChanged();
}
My question is why doesn't my listview update when I click on my button. I don't understand it because I have used adapter.NotifyDataSetChanged(); but it doesn't work. Is there something I've been missing?
This code only add the item to the list, but doesn't update the array adapter:
tasks.Add(listItem);
Either add the item directly to the adapter:
adapter.Add(listItem);
or after you add the item to the list, clear the adapter and re-add the list to it:
adapter.Clear();
adapter.Add(tasks);
Related
I have BindingSource that attached to grid control like this
private BindingSource listDepartmentDto = new();
private async Task LoadDataAsync()
{
listDepartmentDto.DataSource = await departmentService.GetAllDepartmentsAsync();
gridControl1.DataSource = listDepartmentDto;
}
And I binding Controls like this
private void BindingControls()
{
var departmentDto = listDepartmentDto.Current as DepartmentDto;
txtID.DataBindings.Add(new Binding("EditValue", listDepartmentDto, nameof(departmentDto.IdDepartment)));
txtTitle.DataBindings.Add(new Binding("EditValue", listDepartmentDto, nameof(departmentDto.NameDepartment)));
txtDescription.DataBindings.Add(new Binding("EditValue", listDepartmentDto, nameof(departmentDto.DescriptionDepartment)));
}
And I use CurrentChanged event like this
listDepartmentDto.CurrentChanged += new EventHandler(listDepartmentDtoChanged);
private void listDepartmentDtoChanged(object sender,EventArgs e)
{
var departmentDto = listDepartmentDto.Current as DepartmentDto;
if (departmentDto.IdDepartment == 0)
{
btnSave.Text = Resources.Save;
btnNew.Enabled = false;
btnDelete.Enabled = false;
txtTitle.Focus();
return;
}
btnSave.Text = Resources.Edit;
btnNew.Enabled = true;
btnDelete.Enabled = true;
}
And in btnNew click event like this
private async void btnNew_Click(object sender, EventArgs e)
{
listDepartmentDto.AddNew();
await Permission();
}
The problem is when I click on btnNew it create blank row and when I select an other row and click again on btnNew it create new blank row and so on.
How can I prevent this behavior? and if the user move to an other row without entry any data the row removed automatically
The grid view edtiable has set to false.
the grid view (add,remove) row has set to false.
I am new on xamarin and i am trying to save my checkbox state even if the app is closed because when i close it the checkbox reset to uncheck state...
also.. the image that was changed resets.. is there any way to preserve both?
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.layout1);
var seletor = FindViewById<CheckBox>(Resource.Id.checkBox1);
var imagem = FindViewById<ImageView>(Resource.Id.imageView1);
seletor.Click += (o, e) => {
if (seletor.Checked)
imagem.SetImageResource(Resource.Drawable.estado1);
else
imagem.SetImageResource(Resource.Drawable.estado2);
};
}
Have you tried to use the Preferences?
Check the following: How to save user settings
Store the option selected onclose or suspend.. and retrieve onResume / OnLoad
Something like:
// Function called from OnDestroy
protected void saveset(){
//store
var prefs = Application.Context.GetSharedPreferences("MyApp", FileCreationMode.Private);
var prefEditor = prefs.Edit();
prefEditor.PutString("PrefName", "Some value");
prefEditor.Commit();
}
// Function called from OnCreate
protected void retrieveset()
{
//retreive
var prefs = Application.Context.GetSharedPreferences("MyApp", FileCreationMode.Private);
var somePref = prefs.GetString("PrefName", null);
//Show a toast
RunOnUiThread(() => Toast.MakeText(this, somePref, ToastLength.Long).Show());
}
as in the link provided.
Of course you'll need to adapt to your needs and get / populate the value of the checkbox.
If you want, you can also implement some kind of db and use the same mechanism to persist and retrieve settings.
This is usually what I use to store settings and persist values that I need to "remember"
This is an example of how I'm using the same behavior in one app.. not for a checkbox.. but you can see how it works. I removed some code, but I think should be a good example.
[Activity(Label = "#string/ApplicationName",
Icon = "#drawable/Icon")]
public class PersonalDetailsActivity : Activity
{
...
private ISharedPreferencesEditor prefEditor;
private ISharedPreferences preferences;
...
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.PersonalDetailView);
preferences = Application.Context.GetSharedPreferences("AppName", FileCreationMode.Private);
PopulatePersistedData();
}
private void PopulatePersistedData()
{
myId = preferences.GetInt(nameof(myData.Id), 0);
name.Text = preferences.GetString(nameof(myData.Name), null);
address.Text = preferences.GetString(nameof(myData.Address), null);
city.Text = preferences.GetString(nameof(myData.City), null);
county.Text = preferences.GetString(nameof(myData.County), null);
emailAddress.Text = preferences.GetString(nameof(myData.Email), null);
phoneNumber.Text = preferences.GetString(nameof(myData.PhoneNumber), null);
bio.Text = preferences.GetString(nameof(myData.Bio), null);
rating.Rating = 5;
}
private void SaveButton_Click(object sender, EventArgs e)
{
prefEditor = preferences.Edit();
myData = new Citizen();
myData.Name = name.Text;
myData.Address = address.Text;
myData.City = city.Text;
myData.County = county.Text;
myData.Email = emailAddress.Text;
myData.PhoneNumber = phoneNumber.Text;
myData.Bio = bio.Text;
prefEditor.PutInt(nameof(myData.Id), myId);
prefEditor.PutString(nameof(myData.Name), myData.Name);
prefEditor.PutString(nameof(myData.Address), myData.Address);
prefEditor.PutString(nameof(myData.City), myData.City);
prefEditor.PutString(nameof(myData.County), myData.County);
prefEditor.PutString(nameof(myData.Email), myData.Email);
prefEditor.PutString(nameof(myData.PhoneNumber), myData.PhoneNumber);
prefEditor.PutString(nameof(myData.Bio), myData.Bio);
prefEditor.Apply();
prefEditor.Commit();
var intent = new Intent();
intent.PutExtra("CitizenName", name.Text);
SetResult(Result.Ok, intent);
this.Finish();
}
}
Just looking to see if I can find out how i get the item selected in the spinner and store it in a string, i have seen the other posts about this and people say to put this line into code:
(Beneath the last line of the code i posted below)
String Genders = Gender.getSelectedItem().toString();
I try but it gives me a red line underneath (getselecteditem()) - saying spinner does not contain a definition for getselecteditem()
Here is my code:
Spinner Gender;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Form);
var Genders = new String[]
{
"Male", "Female"
};
BaseMale = 2000;
Gender = FindViewById<Spinner>(Resource.Id.spinner1);
Gender.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerDropDownItem, Genders);
Would really appreciate any of your help! :)
you might need to implement the selection handle (ItemSelected) like in this example from https://developer.xamarin.com/guides/android/user_interface/spinner/:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "Main" layout resource
SetContentView (Resource.Layout.Main);
Spinner spinner = FindViewById<Spinner> (Resource.Id.spinner);
spinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs> (spinner_ItemSelected);
var adapter = ArrayAdapter.CreateFromResource (
this, Resource.Array.planets_array, Android.Resource.Layout.SimpleSpinnerItem);
adapter.SetDropDownViewResource (Android.Resource.Layout.SimpleSpinnerDropDownItem);
spinner.Adapter = adapter;
}
and here is the handle, the index to selected item appears as e.Position here.
private void spinner_ItemSelected (object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner spinner = (Spinner)sender;
string toast = string.Format ("The planet is {0}", spinner.GetItemAtPosition (e.Position));
Toast.MakeText (this, toast, ToastLength.Long).Show ();
}
I create ListView using ListAdapter on Android Xamarin. I am using it on Activity which extend ListActivity
This is my code
ListAdapter = new ArrayAdapter<string> (
this,
Android.Resource.Layout.SimpleListItem1,
new string[] { "tes1", "tes2", "tes3" }
);
When I put that in Oncreate() it shown. But I do need that ListAdapter to bind some data when some event (says download completed event) so I put it in a method which I call after download data completed but why ListAdapter can't be shown? My ListView become empty. I am using the same code as above.
this is my OnCreate method
base.OnCreate(bundle);
_DataTopStories = new TopStoriesViewModel();
_DataService = new DataService();
SetContentView(Resource.Layout.ListTopStoriesLayout);
_DataService.GetTopStories();
_DataService.DownloadCompleted += _DataService_DownloadCompleted;
this is Download Event Completed
void _DataService_DownloadCompleted(object sender, EventArgs e)
{
var raw = ((DownloadEventArgs)e).ResultDownload;
if(raw!=null)
{
_DataTopStories = JsonConvert.DeserializeObject<TopStoriesViewModel>(raw);
CreateList();
Log.Info("ds", "download completed");
}
}
this is CreateList() method
private void CreateList()
{
Log.Info("ds", "list");
ListAdapter = new ArrayAdapter<string>(Application.Context, Android.Resource.Layout.SimpleListItem1, new string[] { "tes4", "tes52", "tes6" });
Log.Info("ds", "set adapter");
}
And in Android logcat "set adapter" will not shown. It looks stopped on ListAdapter.
Ok. Found my solution. To update ListAdapter I need to run it on UI Thread so this is my new Download Completed Event
void _DataService_DownloadCompleted(object sender, EventArgs e)
{
var raw = ((DownloadEventArgs)e).ResultDownload;
if(raw!=null)
{
_DataTopStories = JsonConvert.DeserializeObject<TopStoriesViewModel>(raw);
RunOnUiThread(() => CreateList());
//CreateList();
Log.Info("ds", "download completed");
}
}
I have created a dynamic grid view using Itemplate .now i have also created a dynamic drop down list in the grid . how to create a event handler for on selectedindexchange .
i created a slectedindexchange event but it didnt work .the control never passes to the event ?
what to do create a event handler
public class DynamicGridViewTextTemplate : ITemplate
{
string _ColName;
DataControlRowType _rowType;
int _Count;
details Details1 = new details();
public DynamicGridViewTextTemplate(string ColName, DataControlRowType RowType)
{
_ColName = ColName;
_rowType = RowType;
}
public DynamicGridViewTextTemplate(DataControlRowType RowType, int ArticleCount)
{
_rowType = RowType;
_Count = ArticleCount;
}
public void InstantiateIn(System.Web.UI.Control container)
{
switch (_rowType)
{
case DataControlRowType.Header:
Literal lc = new Literal();
lc.Text = "<b>" + _ColName + "</b>";
DropDownList ddl = new DropDownList();
ddl.AutoPostBack = true;
ddl.SelectedIndexChanged += new EventHandler(this.ddl_SelIndexChanged);
container.Controls.Add(lc);
container.Controls.Add(ddl);
break;
case DataControlRowType.DataRow:
//Label lbl = new Label();
//lbl.DataBinding += new EventHandler(this.lbl_DataBind);
LinkButton lb = new LinkButton();
lb.DataBinding += new EventHandler(this.lbl_DataBind);
lb.OnClientClick +=new EventHandler(this.lb_Click);
//lbl.Controls.Add(lb);
container.Controls.Add(lb);
break;
case DataControlRowType.Footer:
Literal flc = new Literal();
flc.Text = "<b>Total No of Articles:" + _Count + "</b>";
container.Controls.Add(flc);
break;
default:
break;
}
}
private void lb_Click(Object sender, EventArgs e)
{
details1.lbl_Click(sender, e);
}
private void lbl_DataBind(Object sender, EventArgs e)
{
//Label lbl = (Label)sender;
LinkButton lbl = (LinkButton)sender;
GridViewRow row = (GridViewRow)lbl.NamingContainer;
lbl.Text =DataBinder.Eval(row.DataItem, _ColName).ToString();
}
public void ddl_SelIndexChanged(Object sender, EventArgs e)
{
Details1.ddlFilter_SelectedIndexChanged(sender,e);
}
}
you can declare you selectedindexchanged event like this:
ddlFilter.SelectedIndexChanged += new EventHandler(ddl2_SelectedIndexChanged);
ddlFilter.AutoPostBack = true;
void ddlFilter_SelectedIndexChanged(object sender, EventArgs e)
{
//your code
}
The reason your event wasn't called is the AutoPostBack=true field. If you don't set it to true your selectedIndexChanged event will never be called.
Whenever I create a new Control in an ASP web page I follow this boiler plate (note that I added some example controls so it's not a "clean" boiler plate):
namespace Components {
[ToolboxData("<{0}:MyControl runat=server></{0}:MyControl>")]
public class MyControl : WebControl, INamingContainer {
// todo: add controls that are created dynamically
private GridView gridView;
public MyControl () {
Initialize();
}
[Browsable(false)]
public override ControlCollection Controls {
get { EnsureChildControls(); return base.Controls; }
}
protected override void OnLoad(EventArgs e) {
// todo: attach event listeners for instance
base.OnLoad(e);
}
protected override void CreateChildControls() {
Initialize();
}
protected override void Render(HtmlTextWriter writer) {
if (DesignMode) {
// If special design mode rendering
return;
}
base.Render(writer);
}
/// This is where the controls are created
private void Initialize() {
base.Controls.Clear();
// todo: Create all controls to add, even those "added later"
// if something is generated but should not be shown,
// set its Visible to false until its state is changed
Label exampleLabel = new Label();
exampleLabel.Visible = false; // like so
if (gridView == null) { gridView = new GridView(); }
base.Controls.Add(exampleLabel);
base.Controls.Add(gridView);
}
}
}
Now, if you create your dynamic drop down in Initialize and add it to your Controls collection every time but only set its Visibility to true when you want it to show, your event should be triggered, since the id's of your controls should be the same between postbacks.
Dynamic control's event to occure, it is required that it should be created and event assigned in page_load event or during the page_load event occures. Control's event will fire after Page_Load event completes. If control is not recreated in page_load event, event will not bind to the control and will not fire.
I had the same problem and I was creating the dynamic ddl inside (!Page.IsPostBack). When i moved the creation outside the (!Page.IsPostBack) it worked fine.
You must create your elements outside the (!Page.IsPostBack) like MUG4N said and it should work fine.
Thats how I did it with a Dropdownlist generated out of a ComboBox
code :
setConnectionToolStripMenuItem.DropDownItems.AddRange(toolStripComboBoxConnections.Items.Cast<string>().Select(text => new ToolStripMenuItem(text, null, new EventHandler(DropDown_Click_Event))).ToArray());