I have DataGridView with several cells. How to validate all cells and highlight invalidated cells?
Validation should work after filling cells.
I tried to use this way:
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
}
But I need to set some validation rules for each fields(columns). For example, check on number or string.
You can try this code.
When We are going to edit cell('EmployeeName') it avoid from integer values.
When focus lost in selected cell Display the error Message.
this is My model
namespace WindowsFormsApplication1
{
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public string EmployeeAddress { get; set; }
}
}
this is My code
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
List<Employee> EmployeeList = new List<Employee>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Employee emp = new Employee();
emp.EmployeeAddress = "polonnaruwa";
emp.EmployeeId = 1;
emp.EmployeeName = "Kasun";
EmployeeList.Add(emp);
Employee emp1 = new Employee();
emp1.EmployeeAddress = "Kandy";
emp1.EmployeeId = 2;
emp1.EmployeeName = "Bimal";
EmployeeList.Add(emp1);
Employee emp2 = new Employee();
emp2.EmployeeAddress = "New Town";
emp2.EmployeeId = 3;
emp2.EmployeeName = "ASheain";
EmployeeList.Add(emp2);
dataGridView1.DataSource = EmployeeList;
}
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (this.dataGridView1.Columns[e.ColumnIndex].Name == "EmployeeName")
{
int RowIndex = e.RowIndex;
int columnIndex = e.ColumnIndex;
if (e.Value != null)
{
string stringValue = (string)e.Value;
int val;
if (int.TryParse(stringValue, out val))
{
label1.Text = "it is integer";
dataGridView1.Rows[RowIndex].Cells[columnIndex].Value = "Please Enter String Value";
}
else
{
label1.Text = "it is not integer";
}
}
}
}
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
}
}
}
Related
I try to do that the func Form1_Load will display the city list.
I dont know how can i link the 3 functions of the cities (JerusalemData(), LondonData(), OttawaData()) to the function FillCitiesData();
The problem is that it doesnt show the list but only the streets without choosing a city. Another problem - in HouseNum_ValueChanged it doesnt show numbers and you can also type letters and not just numbers.
This is my code - I'll be happy if anyone can help me find the problem.
namespace PlanYourParty
{
public partial class Form1 : Form
{
List <City> cities;
List <string> streets;
public Form1()
{
InitializeComponent();
FillCitiesData();
}
public void FillCitiesData()
{
cities = new List<City>();
cities.Add(new City() { Code = "123", Name = "Jerusalem" });
cities.Add(new City() { Code = "456", Name = "London" });
cities.Add(new City() { Code = "789", Name = "Ottawa" });
JerusalemData();
LondonData();
OttawaData();
}
private void Form1_Load(object sender, EventArgs e)
{
FillCitiesData();
cmbCity.DataSource = cities;
cmbCity.DisplayMember = "Name";
cmbCity.ValueMember = "Code";
cmbCity.SelectedIndexChanged += cmbCity_SelectedIndexChanged;
}
public void JerusalemData()
{
streets = new List<string>();
cmbStreet.Items.Clear();
cmbStreet.Items.Add("Admond Peleg");
cmbStreet.Items.Add("Pardes");
cmbStreet.Items.Add("Nayman");
}
public void LondonData()
{
streets = new List<string>();
cmbStreet.Items.Clear();
cmbStreet.Items.Add("Oxford Street");
cmbStreet.Items.Add("Piccadilly");
cmbStreet.Items.Add("Highfield Ave");
}
public void OttawaData()
{
streets = new List<string>();
cmbStreet.Items.Clear();
cmbStreet.Items.Add("Riverside Drive");
cmbStreet.Items.Add("Ontario Highway");
cmbStreet.Items.Add("Moodie Drive");
}
private void cmbCity_SelectedIndexChanged(object sender, EventArgs e)
{
if (sender != null && sender as City != null)
{
string code;
code = (sender as City).Code;
if (code == "123")
{
JerusalemData();
}
else if (code == "456")
{
LondonData();
}
else OttawaData();
}
}
private void cmbStreet_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void domainUpDownHouseNumber_SelectedItemChanged(object sender, EventArgs e)
{
}
private void Form1_Load_1(object sender, EventArgs e)
{
}
}
First I suggest you separate your data model from the UI. Pull everything you need to define cities and streets in the City class. I have included two methods that return the cities in the example, and the streets for each city.
No need for separate methods that do the same thing, but with different data.
City.cs
public class City
{
public string Code { get; set; }
public string Name { get; set; }
public IList<string> Streets { get => GetStreets(this); }
public static List<City> GetCities()
{
var cities = new List<City>();
cities.Add(new City() { Code = "123", Name = "Jerusalem" });
cities.Add(new City() { Code = "456", Name = "London" });
cities.Add(new City() { Code = "789", Name = "Ottawa" });
return cities;
}
public static List<string> GetStreets(City city)
{
var streets = new List<string>();
if (city == null) return streets;
switch (city.Code)
{
case "123":
streets.Add("Admond Peleg");
streets.Add("Pardes");
streets.Add("Nayman");
break;
case "456":
streets.Add("Oxford Street");
streets.Add("Piccadilly");
streets.Add("Highfield Ave");
break;
case "789":
streets.Add("Riverside Drive");
streets.Add("Ontario Highway");
streets.Add("Moodie Drive");
break;
default:
throw new ArgumentException("Unknown city code.");
}
return streets;
}
}
Then write the UI such that the controls contain the lists of items as specified by the City.GetCities() and City.GetSreets() methods.
The currently selected city and street are returned by CurrentCity and CurrentStreet as well as their corresponding index in the combobox in CurrentCityIndex and CurrentStreetIndex.
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
cityComboBox.DataSource = City.GetCities();
cityComboBox.DisplayMember = nameof(CurrentCity.Name);
cityComboBox.ValueMember = nameof(CurrentCity.Code);
cityComboBox.SelectedIndexChanged += CityComboBox_SelectedIndexChanged;
cityComboBox.SelectedIndex = -1; // remove default selection of 1st item.
streetComboBox.DataSource = Array.Empty<string>();
streetComboBox.SelectedIndexChanged += StreetComboBox_SelectedIndexChanged;
}
private void CityComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// TODO: Things when a city is selected.
streetComboBox.DataSource = CurrentCity?.Streets;
streetComboBox.SelectedIndex = -1; // remove default selection of 1st item.
UpdateLabels();
}
private void StreetComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// TODO: Things when a street is selected.
UpdateLabels();
}
public void UpdateLabels()
{
cityInfo.Text = CurrentCityIndex >= 0 ? $"#{CurrentCity.Code} {CurrentCity.Name}" : "Please select a city.";
streetInfo.Text = CurrentStreetIndex >= 0 ? CurrentStreet : "Please select a street.";
}
public List<City> AllCities { get => cityComboBox.DataSource as List<City>; }
public List<string> AllStreets { get => streetComboBox.DataSource as List<string>; }
public int CurrentCityIndex { get => cityComboBox.SelectedIndex; }
public int CurrentStreetIndex { get => streetComboBox.SelectedIndex; }
public City CurrentCity { get => cityComboBox.SelectedItem as City; }
public string CurrentStreet { get => streetComboBox.SelectedItem as string; }
}
Screen Shots
After binding the datasource, the rows would grow after click. but the all rows are blank. How could I solve this ?
BindingList<Info> infos = new BindingList<Info>();
private void button5_Click(object sender, EventArgs e)
{
dataGridView2.DataSource = infos;
infos.Add(new Info("asadasdasds", "asasdafasdfed"));
}
class Info
{
public string a = "";
public string b = "";
public Info(string aa, string bb)
{
a = aa;b = bb;
}
}
I'm having a problem understanding what code I can use bring back selected rows from data grid view to the text boxes to edit. I think we will use something like dataScreen.SelectedRows something maybe
What code can I use?
DataSource = datagridview (to make it easier to understand)
namespace HospitalManagementSystem
{
public partial class Form1 : Form
{
DataTable table = new DataTable();
public string name { get; set; }
public string Gender { get; set; }
public string DateOfBirth { get; set; }
public string Address { get; set; }
public string MedicalHistory { get; set; }
public string BloodType { get; set; }
public Form1()
{
InitializeComponent();
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
dataScreen.Rows.Add("Iqra", "Female", 20, 721797684, "praha 6", "Migraine", "Blood Type O+");
}
private void radioButton_Male_CheckedChanged(object sender, EventArgs e)
{
Gender = "Male";
}
private void radioButton_Female_CheckedChanged(object sender, EventArgs e)
{
Gender = "Female";
}
private void btnSave_Click(object sender, EventArgs e)
{
name = txtName.Text;
DateOfBirth = Date_dob.Value.ToString();
Address = txtAddress.Text;
MedicalHistory = txtMedicalHistory.Text;
BloodType = txtBloodType.Text;
if (radioButton_Female.Checked)
Gender = "Female";
else if (radioButton_Male.Checked)
Gender = "Male";
dataScreen.Rows.Add(name, Gender, DateOfBirth, Address, MedicalHistory);
}
}
}
It looks like you replace the DataSource of your dataScreen with the value of your table when you click on save.
dataScreen.DataSource = table;
That is what's replacing the value of dataScreen.DataSource.
Depending on what you are trying to do you might want to add that row to the table before you update your dataScreen.DataSource.
I have two forms a salaried employee and an hourly employee which has the employees details on it loading from a textfile. In my main form there is a listbox with the names of the employees, once one is clicked, i want to be able to press an edit employee details button on my main form and for the correct form to come up and I am struggling on how to do this. The code for my main form is here:
public partial class MainForm : Form
{
// The file used to store employee details
string employeesFile = "employees.txt";
// The collection used to hold the employee data
Employees employees;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
employees = new Employees();
if (!employees.Load(employeesFile))
{
MessageBox.Show("Unable to load employees file");
}
else
{
PopulateListBox();
}
}
private void PopulateListBox()
{
listBoxEmployees.Items.Clear();
foreach (Employee employee in employees)
{
listBoxEmployees.Items.Add(employee.LastName + "," +
employee.FirstName);
}
listBoxEmployees.SelectedIndex = 0;
}
private void listBoxEmployees_DoubleClick(object sender, EventArgs e)
{ }
private void buttonEdit_Click(object sender, EventArgs e)
{
}
my load method:
{
public bool Load(string employeesFile)
{
bool status = false;
StreamReader inputFile = null;
string inputLine;
if (!File.Exists(employeesFile))
{
return false;
}
try
{
inputFile = new StreamReader(employeesFile);
if (inputFile != null)
{
inputLine = inputFile.ReadLine();
while (inputLine != null)
{
Employee employeeEntry =
EmployeeClass.NewEmployee(inputLine);
if (employeeEntry != null)
{
this.Add(employeeEntry);
}
inputLine = inputFile.ReadLine();
}
inputFile.Close();
}
status = true;
}
catch
{
}
return status;
}
}
the employees class code from the load method:
public class EmployeeClass
{
public static Employee NewEmployee(string employeeData)
{
if (employeeData.Length < 1)
{
return null;
}
switch (employeeData[0])
{
case 'S':
return new SalariedEmployee(employeeData);
case 'H':
return new HourlyEmployee(employeeData);
default:
return null;
the hourly employee form:
public partial class Hourly_Employee : Form {
HourlyEmployee _employeeEntry;
public Hourly_Employee()
{
InitializeComponent();
}
public HourlyEmployee employeeEntry
{
get
{
return _employeeEntry;
}
set
{
_employeeEntry = value;
}
}
private void Hourly_Employee_Load(object sender, EventArgs e)
{
textBoxlastName.Text = _employeeEntry.LastName;
textBoxfirstName.Text = _employeeEntry.FirstName;
textBoxaddress.Text = _employeeEntry.Address;
textBoxpostCode.Text = _employeeEntry.PostCode;
textBoxphoneNumber.Text = _employeeEntry.PhoneNumber;
dateTimePickerdateOfBirth.Text =
_employeeEntry.DateOfBirth.ToString();
textBoxhourlyPay.Text = _employeeEntry.HourlyPay.ToString();
textBoxoverTimePay.Text = _employeeEntry.OvertimePay.ToString();
}
}
and lastly my salaried employee form:
public partial class Salary_Employee : Form
{
SalariedEmployee _employeeEntry;
public SalariedEmployee employeeEntry
{
get
{
return _employeeEntry;
}
set
{
_employeeEntry = value;
}
}
private void Salary_Employee_Load(object sender, EventArgs e)
{
textBoxlastName.Text = _employeeEntry.LastName;
textBoxfirstName.Text = _employeeEntry.FirstName;
textBoxaddress.Text = _employeeEntry.Address;
textBoxpostCode.Text = _employeeEntry.PostCode;
textBoxphoneNumber.Text = _employeeEntry.PhoneNumber;
dateTimePickerdateOfBirth.Text =
_employeeEntry.DateOfBirth.ToString();
textBoxSalary.Text = _employeeEntry.Salary.ToString();
}
any help with this issue would be great!!
The trick is to add the employee objects to the listbox instead of only strings containing the employee names. This allows you to retrieve the selected employee directly from the listbox. Otherwise you would need a way to find the employee object belonging to a name.
Use the type of the selected item to determine the employee type and the employee form.
private void buttonEdit_Click(object sender, EventArgs e)
{
// Get the selected employee from the listBox.
object employee = listBoxEmployees.SelectedItem;
if (employee != null) { // An employee has been selected.
// Use the new C# 7.0 switch syntax in order to switch by employee type.
switch (employee) {
case SalariedEmployee sEmployee:
var sfrm = new Salary_Employee(); // Open the salaried employee form..
sfrm.employeeEntry = sEmployee;
sfrm.Show();
break;
case HourlyEmployee hEmployee:
var hfrm = new Hourly_Employee(); // Open the hourly employee form.
hfrm.employeeEntry = hEmployee;
hfrm.Show();
break;
}
}
}
In case you are using an older C# version you can test a type with
if (employee is SalariedEmployee) {
var frm = new Salary_Employee();;
frm.employeeEntry = (SalariedEmployee)employee;
frm.Show();
} else if (employee is HourlyEmployee) {
var frm = new Hourly_Employee();
frm.employeeEntry = (HourlyEmployee)employee;
frm.Show();
}
By default, an object's ToString method returns the name of the object's type. Enable the listbox to display the employees correctly by overriding the ToString method inherited from object in the common base class Employee.
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return LastName + ", " + FirstName;
}
}
I have some label that should display actual amount of items that contain BindingList that bound to the DataGridView.
I tried to bind in this way:
CountOfLoadedItemsLabel.DataBindings.Add("Text", _items.Count, String.Empty);
But when BindingList updates, the label that bound to its Count property not changes.
Never used BindingList<T> but this worked for me:
public partial class Form1 : Form
{
private BindingList<Test> list;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.list = new BindingList<Test>
{
new Test(1,"Entry"),
new Test(2,"Another Entry")
};
dataGridView1.DataSource = new BindingSource(list,null);
list.ListChanged += list_ListChanged;
list.Add(new Test(3, "After Binding"));
}
void list_ListChanged(object sender, ListChangedEventArgs e)
{
CountOfLoadedItemsLabel.Text = string.Format("Items: {0}", list.Count);
}
}
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
public Test(int id, string name)
{
this.Id = id;
this.Name = name;
}
}