I've made a contacts app in Xamarin and wanted to incorporate the SwipeView, but I can't figure out how to delete single contacts from my list. Any help?
using System;
using System.Collections.Generic;
using SQLite;
using System.Linq;
using Contacts.Classes;
using Xamarin.Forms;
using System.Diagnostics;
namespace Contacts
{
public partial class ContactsPage : ContentPage
{
public ContactsPage()
{
InitializeComponent();
Device.SetFlags(new[] {"SwipeView_Experimental"});
}
void NewContactToolbarItem_Clicked(System.Object sender, System.EventArgs e)
{
Navigation.PushAsync(new MainPage());
}
protected override void OnAppearing()
{
base.OnAppearing();
using(SQLiteConnection conn = new SQLiteConnection(App.FilePath))
{
conn.CreateTable<Contact>();
var contacts = conn.Table<Contact>().ToList();
contactsListView.ItemsSource = contacts;
Command DeleteCommand = new Command<Contact>(contact => { conn.Delete(contact); });
}
}
As Jason said, create a database access class include connection, deleting operation and so on. You could check the database access class in the link below: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/data/databases#data-manipulation-methods
Choose the Item you want to delete and invoke the delete method of SQLite database.
conn.DeleteAsync(item);
After deleting the Item, use the code below to get the list of database and reset the ItemSource.
conn.Table<Contact>().ToListAsync();
You could download the source file from the link below:
https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/todo/
Related
Created an application to insert data into the database using LINQ. I kept the ID column in the database. I am looking for guidance on how to have the ID column automatically add the next ID number each time a new entry is made into the data base?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Week4_2_
{
public partial class Form1 : Form
{
LinqsqlinsertdataDataContext objcontxt = new LinqsqlinsertdataDataContext();
public Form1()
{
InitializeComponent();
}
private void buttonInsert_Click(object sender, EventArgs e)//Inserts Records
{
using (objcontxt = new LinqsqlinsertdataDataContext())
{
TblSoccer name = new TblSoccer
{
FirstName = txtFirstName.Text,
LastName = textBox2.Text,
Address = textBox1.Text,
Id = textBoxID.Text
};
objcontxt.TblSoccers.InsertOnSubmit(name);
objcontxt.SubmitChanges();
}
getAllRecords();
}
private void getAllRecords() //Show all records
{
using (objcontxt = new LinqsqlinsertdataDataContext())
{
dataGridView1.DataSource = objcontxt.TblSoccers;
}
}
private void Form1_Load(object sender, EventArgs e)
{
getAllRecords();
}
}
}
In LinqToSQL, it requires primary key to insert or update the row in the Table. So your ID Column will be PK and Identity auto incremented column.
In DBML, you have to select your ID Column go to properties and set below properties:
Auto Generated Value : true and Auto-Sync : OnInsert
I am new to C#, and 1st post here. I'm am writing a windows form app to be used as a database entry tool. to do this I'm connecting to an access database to read lists and capture new inputs
the error I'm getting is:
System.InvalidOperationException: 'ExecuteReader: Connection property has not been initialized.'
at
OleDbDataReader reader = cmd.ExecuteReader();
The code of the form that is driving the fault is:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
namespace Metrics_Data
{
public partial class Login : Form
{
Welcome conndata = new Welcome();
public Login()
{
InitializeComponent();
}
private void btn_exit_Click(object sender, EventArgs e)
{
this.Close();
}
private void Login_Load(object sender, EventArgs e)
{
}
private void btn_login_Click(object sender, EventArgs e)
{
//Verify Password and UserID
string Password = null;
OleDbCommand cmd = new OleDbCommand("SELECT * from [Users] WHERE UserID = #UserID",conndata.myconn);
cmd.Parameters.Add("#UserID", OleDbType.VarChar).Value = txt_userid;
OleDbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Password = reader["User_Password"].ToString();
}
reader.Close();
cmd.Dispose();
//Load Next Form
UserHome userHomeform = new Metrics_Data.UserHome();
this.Hide();
userHomeform.ShowDialog();
}
}
}
The code that connects from the welcome screen is:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
using Microsoft.Win32;
namespace Metrics_Data
{
public partial class Welcome : Form
{
public OleDbConnection myconn = null;
public Welcome()
{
try
{
InitializeComponent();
OleDbConnection myconn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\148.96.211.237\GroupShares\Quality\Electronic Checksheets\MD.accdb;jet OLEDB:Database Password=""Warranty""");
myconn.Open();
lbl_Connstatus.Text = "Connected to DB";
p_dbconn.Visible = true;
}
catch(Exception)
{
MessageBox.Show("error connecting to DB");
btn_cfg.Visible = false;
btn_home.Visible = false;
btn_help.Visible = true;
}
}
class Variables
{
public static dynamic LoginType;
public static dynamic UserID;
public static dynamic Admin;
public static dynamic FirstUse;
public static dynamic Zone;
public static dynamic Shift;
public static dynamic Group;
public static dynamic CDate;
public static dynamic GateLevel;
public static dynamic CountermeasureID;
}
private void Welcome_Load(object sender, EventArgs e)
{
}
private void btn_help_Click(object sender, EventArgs e)
{
//If program is unable to connect with database, initiate sequence where computer's installed access database engine's are displayed in popups, then tell user that program cannot connect
//popups are displayed to help user. If no database engine popups are displayed, see the following URL for troubleshooting information:
//https://support.microsoft.com/en-us/help/2874601/can-t-use-the-access-odbc-driver-or-oledb-provider-outside-office-clic
//A possible fix to this problem is to install access runtime 2013. The URL below has the link to where it's stored locally:
//\\10.35.193.112\Open\AccessRuntime2013
//Update: This also resolves concerns for computers with MS Office 2016, in which the user will receive a popup indicating they have an OLEDB database engine, but the program still will
//not work. IT may be required to give users temporary administrative rights to install AccessRuntime2013.
string AccessDBAsValue = string.Empty;
RegistryKey rkACDBKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Classes");
if (rkACDBKey != null)
{
foreach (string subKeyName in rkACDBKey.GetSubKeyNames())
{
if (subKeyName.Contains("Microsoft.ACE.OLEDB"))
{
MessageBox.Show(Convert.ToString(subKeyName));
}
}
}
MessageBox.Show("The program was unable to connect to the database.");
}
private void btn_exit_Click(object sender, EventArgs e)
{
Environment.Exit(1);
}
private void btn_home_Click(object sender, EventArgs e)
{
Login loginform = new Metrics_Data.Login();
Variables.LoginType = "Data Entry";
loginform.ShowDialog();
}
Any ideas of what I am doing wrong here??? I have verified path to database and the connection string at initial connection does not give any errors, nor do I have any errors in the error space on visual studio.
Many Thanks!
As pointed out in the comments, your constructor is hiding the form property myconn with a local variable, so when you reference the form property, it will be null.
However, I'd be remiss if I did not suggest that you NOT store the connection in a form property. ADO.NET Connections are pooled and are generally cheap to create, so just create one when you need one and dispose of it (using using) when you're done with the query it's created for.
You can store the connection string in one place, but sharing connection objects is generally a bad idea.
Not using a shared connection will also make it simpler since you don't have to worry about checking if the connection is open or not, worrying about opening it twice, etc.
I am slamming my head against the wall trying to figure out why when I click the button, a NullReferenceException is saying that my dbcontext is null at the linq query!!! I don't understand, as I have the dbcontext get filled when the form loads with a hospital entity (see below):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DisplayPatientsTable
{
public partial class PatientForm : Form
{
public PatientForm()
{
InitializeComponent();
}
//Entity Framework dbcontext. All data passes through this object and the database
private HospitalDatabase.HospitalEntities dbcontext = null;
private void PatientForm_Load(object sender, EventArgs e)
{
RefreshPatients();
}
private void RefreshPatients()
{
//Dispose of old dbcontext, if any
if (dbcontext != null)
{
dbcontext.Dispose();
//create new dbcontext so we can reorder records based on edits
dbcontext = new HospitalDatabase.HospitalEntities();
//use LINQ to order the Addresses table contents by last name, then first name
dbcontext.Patients.OrderBy(Patients => Patients.Pat_Last_Name)
.ThenBy(Patients => Patients.Pat_First_Name)
.Load();
// specify DataSource for PatientsBindingSource
patientBindingSource.DataSource = dbcontext.Patients.Local;
patientBindingSource.MoveFirst(); // go to the first result
textBox1.Clear(); //clear the Find TextBox
}
}
private void pat_First_NameLabel_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
// use LINQ to create a data source that contains only people
// with last names that start with the specified text
// use LINQ to filter contacts with last names that
// start with findTextBox contents
//Entity Framework dbcontext. All data passes through this object and the database
if (dbcontext != null)
{
dbcontext.Dispose();
//create new dbcontext so we can reorder records based on edits
dbcontext = new HospitalDatabase.HospitalEntities();
}
var query = from patient in dbcontext.Patients
where patient.Pat_Last_Name.StartsWith(textBox1.Text)
orderby patient.Pat_Last_Name, patient.Pat_First_Name
select patient;
//display matching contacts
// patientBindingSource.DataSource = query.ToList();
// patientBindingSource.MoveFirst(); //
// don't allow add/delete when contacts are filtered
bindingNavigatorAddNewItem.Enabled = false;
bindingNavigatorDeleteItem.Enabled = false;
}
private void button2_Click(object sender, EventArgs e)
{
// allow add/delete when contacts are not filtered
bindingNavigatorAddNewItem.Enabled = true;
bindingNavigatorDeleteItem.Enabled = true;
RefreshPatients(); //change back to initial unfiltered data
}
private void patientBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
Validate(); // validate input fields
patientBindingSource.EndEdit();
//try to save changes
if (dbcontext == null)
{
MessageBox.Show("FirstName and LastName must contain values");
}
dbcontext.SaveChanges();
RefreshPatients();
}
}
}
You're only running the following line if dbcontext != null... but it's null when your form first loads, so the code inside that if block is never going to execute.
dbcontext = new HospitalDatabase.HospitalEntities();
You'll have to rework your logic. Maybe something as simple as this, where you check the value before disposing of the object, but then run the rest of the code regardless.
//Dispose of old dbcontext, if any
if (dbcontext != null)
dbcontext.Dispose();
//create new dbcontext so we can reorder records based on edits
dbcontext = new HospitalDatabase.HospitalEntities();
Note that I can't comment on whether disposing and creating a new entity like this is a good practice - I'm not familiar enough with the technology. I'll trust that it is.
I can't use a simple class in aspx.cs file. I know i should include some code to declare this class before creating an instance like
User user = new User();
, but I don't know the syntax. I'm new to C# and ASP.net, as you see, and can have other errors in logic so any help is appreciated
This is how my website structure looks like:
This is the code of User.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class User
{
public int Id
{
get { return id; }
set { id = value; }
}
public String Username
{
get { return username; }
set { username = value; }
}
public String Password
{
get { return password; }
set { password = value; }
}
}
This is the code of Default.aspx.cs:
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MySql.Data.MySqlClient;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
doSomething();
}
}
private void doSomething() {
User user = new User(); // error is shown
}
}
use ctr+. placing cursor in the user and you will get help on that.
Edit 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DBConnection.model.business
{
public class User
{
...
Then using like below in your default.aspx
using DBConnection.model.business;
You can get the reference of your class.
Add using DBConnection.model.business;
or
Point user object and click mouse right click
Select resolve
I have designed a WinForm which is bound to my database using ADO.Net Entity Framework. On load my details form is populated with data from the database.
I can navigate through the items, however I can not add, save or update the item.
Below is the code for my form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
cpdEntities dbcontext;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dbcontext = new cpdEntities();
cpd_recipientsBindingSource.DataSource = dbcontext.cpd_recipients.ToList();
}
private void cpd_recipientsBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
dbcontext = new cpdEntities();
dbcontext.SaveChanges();
}
}
}
Here is a simple example working with EntityFramework 4
How to Load:
using (var con = new cpdEntities())
{
cpd_recipientsBindingSource.DataSource = con.cpd_recipients.ToList();
}
How to Insert and Update:
if (cpd_recipientsBindingSource.Current == null) return;
using (var con = new cpdEntities())
{
var p = new Customer()
{
CustomerId = ((cpd_recipients)cpd_recipientsBindingSource.Current).Id,
CustomerIdNo = IdNoTextBox.Text,
CustomerName = CustomerNameTextBox.Text
};
var cus = new Customer();
if (p.CustomerId > 0)
cus = con.Customers.First(c => c.CustomerId == p.CustomerId);
cus.CustomerId = p.CustomerId;
cus.CustomerIdNo = p.CustomerIdNo;
cus.CustomerName = p.CustomerName;
if (p.CustomerId == 0)
con.Customers.AddObject(cus);
con.SaveChanges();
int i = cus.CustomerId;//SCOPE_IDENTITY
}
}
It looks like your re-instantiating your DbContext class in each of the events. Remove re-insantiating the DbContext from your saveItem event and give it a try again.