Combobox displays ValueMember instead of DisplayMember - winforms

I have a simple class User like below:
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string FullName
{
get
{
return Name + " " + Surname;
}
}
}
Then I have form frmProcess, which displays list of Users in combobox, like below. The problem is, that if I set DisplayMember to FullName then what is displayed is UserId column. What's weird is that if I set DisplayMember to Surname, then Surname is displayed. What am I doing wrong?
public partial class frmProcess : Form
{
List<User> Users;
private async void frmProcess_Load(object sender, EventArgs e)
{
Users = new List<User>();
User A = new User { UserId = 1, Name = "Michael", Surname = "Smith" };
User B = new User { UserId = 2, Name = "John", Surname = "Johnson" };
Users.Add(A);
Users.Add(B);
cmbStartedBy.DataSource = Users;
cmbStartedBy.DisplayMember = "FullName";
cmbStartedBy.ValueMember = "UserId";
}
}

I have run your exact code in a winforms application in VS2013 and get this:
EDIT: The only difference is the async on Form load.
Entire code:
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 WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
List<User> Users;
private void Form1_Load(object sender, EventArgs e)
{
Users = new List<User>();
User A = new User { UserId = 1, Name = "Michael", Surname = "Smith" };
User B = new User { UserId = 2, Name = "John", Surname = "Johnson" };
Users.Add(A);
Users.Add(B);
comboBox1.DataSource = Users;
comboBox1.DisplayMember = "FullName";
comboBox1.ValueMember = "UserId";
}
}
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string FullName
{
get
{
return Name + " " + Surname;
}
}
}
}

Ok, found the bug. When I was posting my question I simplified my class and removed, among others, the data annotations. Surprisingly, this made the code work correctly. As it turns out, the problem was caused by FullName property being marked as [Browsable(false)]. I marked it unbrowsable so that this property wasn't displayed in DataGridViews, didn't realize the impact is also on comboboxes.
public class User
{
[DisplayName("ID")]
public int UserID { get; set; }
[DisplayName("Imie")]
[Required(AllowEmptyStrings = false, ErrorMessage = "Pole imie nie może być puste!")]
public string Name { get; set; }
[DisplayName("Nazwisko")]
[Required(AllowEmptyStrings = false, ErrorMessage = "Pole nazwisko nie może być puste!")]
public string Surname { get; set; }
[Browsable(false)]// <-- this was causing the issue
public string FullName
{
get
{
return Name + " " + Surname;
}
}
}

Related

Why I couldn't call Model inside my Controller

I have one problem and I have no idea what to do. I am try couple of method but nothing works for me. I have model Patient
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace BergClinic.Models
{
public class Patient
{
[Key]
public int Id { get; set; }
[Required]
[Display(Name ="First Name")]
[MaxLength(50)]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
[MaxLength(50)]
public string LastName { get; set; }
[Required]
[Display(Name = "Date of Birth")]
public DateTime DateOfBirth { get; set; }
[Display(Name = "Address")]
[MaxLength(50)]
public string Address { get; set; }
[Display(Name = "Phone Number")]
public string PhoneNumber { get; set; }
[Display(Name = "Gender")]
public PatientGender Gender { get; set; }
}
public enum PatientGender
{
[Display(Name ="Male")]
Male,
[Display(Name = "Female")]
Female,
Unknown
}
}
And IPatientRepository and PatientRepository which contains following logic:
using BergClinic.DataAccess.Data;
using BergClinic.DataAccess.Repository.IRepository;
using BergClinic.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BergClinic.DataAccess.Repository
{
public class PatientRepository : Repository<Patient>, IPatientRepository
{
private readonly ApplicationDbContext _db;
public PatientRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(Patient patient)
{
var objDb = _db.Patients.FirstOrDefault(s => s.Id == patient.Id);
if (objDb != null)
{
objDb.FirstName = patient.FirstName;
objDb.LastName = patient.LastName;
objDb.DateOfBirth = patient.DateOfBirth;
objDb.Address = patient.Address;
objDb.PhoneNumber = patient.PhoneNumber;
objDb.Gender = patient.Gender;
_db.SaveChanges();
}
}
}
}
And here is IPatientRepository which containt Update method
using BergClinic.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace BergClinic.DataAccess.Repository.IRepository
{
public interface IPatientRepository : IRepository<Patient>
{
void Update(Patient patient);
}
}
Once I creat this in my Admin Area in PatientController I want to initialize object Patient but I couldn't. I want to create Upsert method for Update and Insert Patient but whatever I type It doesn't see my model only what it is see is Patient workspace
'Patient' is a namespace but is used like a type
using BergClinic.DataAccess.Repository.IRepository;
using Microsoft.AspNetCore.Mvc;
using BergClinic.Models;
namespace BergClinic.Areas.Admin.Controllers
{
[Area("Admin")]
public class PatientController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public PatientController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public IActionResult Index()
{
return View();
}
public IActionResult Upsert(int? Id)
{
Patient patient = new Areas.Patient
return View();
}
#region API_CALLS
[HttpGet]
public IActionResult GetAll()
{
var patient = _unitOfWork.Patient.GetAll();
return Json(new { data = patient });
}
#endregion
}
}
Just to notice I use RepositoryPatten and thee way arhitecture. I try to restart Visual Studio but seem nothing happened, I try to remove Project Reference and try to add again, but noting happened againg.
Here is couple of sceen of my ProjectStructures which you can check:

How to save user data globally in C++ Windows Form Application

Here is the button handler that helps to login a user, I will like to retrieve the user data into a global data structure that be used all through the program, something relating to PHP Web Session. How do I implement and retrieve using my code below
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace MySql::Data::MySqlClient;
private: System::Void loginBtn_Click(System::Object^ sender, System::EventArgs^ e) {
String^ email = this->email->Text;
String^ password = this->password->Text;
if (email == " " || password == "") {
MessageBox::Show("Please enter all fields to proceed");
}
else {
String^ connString = L"datasource=127.0.0.1;port=3306;username=root;password=";
MySqlConnection^ connDb = gcnew MySqlConnection(connString);
MySqlCommand^ cmdDb = gcnew MySqlCommand("select * from clocking.users where EMAIL = '" + email + "' AND PASSWORD = '" + password + "' ", connDb);
MySqlDataReader^ myReader;
try {
connDb->Open();
myReader = cmdDb->ExecuteReader();
int row = 0;
while (myReader->Read()) {
row = row + 1;
}
if(row == 1){
MessageBox::Show("Welcome on board! Auth Successful");
}
else {
MessageBox::Show("Incorrect Email/Password Combination. Try again!");
}
}
catch (Exception^ex) {
MessageBox::Show("Error Connecting to System Database!");
}
}
}
Hello Lewa Bammy Stephen, your code is fine, you just have to add a class where you save the user data with its appropriate get and set methods, I show you below.
public bool Login(string Nombre, string Contraseña)
{
using (var conection = Getconection())
{
conection.Open();
using (var command = GetSqlCommand())
{
command.Connection = conection;
command.CommandText = "select * from Usuario where Usuario = #Usuario and claveusu =#claveusu";
command.Parameters.AddWithValue("#Usuario", Nombre);
command.Parameters.AddWithValue("#claveusu", Contraseña);
command.CommandType = CommandType.Text;
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Datoscahe.Iduser = reader.GetInt32(0);
Datoscahe.Name = reader.GetString(1);
Obtenerrol();
}
return true;
}
else
return false;
}
}
}
If you look closely inside the while condition I am telling it to call the Data class cahe so that it saves me the information of the person who started the session indicating what type of value it has and the position it has in the database
namespace Capadatos.SQLserver
{
public static class Datoscahe
{
public static int Idusuario { get; set; }
public static string Nombre { get; set; }
public static string Apellidos { get; set; }
public static string Sexo { get; set; }
public static DateTime Fecha_nacimiento { get; set; }
public static string Num_documento { get; set; }
public static string Direccion { get; set; }
public static string Telefono { get; set; }
public static string Email { get; set; }
public static int Idrol { get; set; }
public static string Usuario { get; set; }
public static string Password { get; set; }
}
}
and this is the class where I keep the user data

Dapper custom SqlMapper.TypeHandler Parse method not called

I created a SqlMapper.TypeHandler to map a Customer object into a CreditAccount class as follows:
public class CustomerTypeHandler : SqlMapper.TypeHandler<Customer>
{
public override Customer Parse(object value)
{
throw new NotImplementedException();
}
public override void SetValue(IDbDataParameter parameter, Customer
value)
{
throw new NotImplementedException();
}
}
public class CreditAccount
{
public int AccountId { get; set; }
public Customer Customer{ get; set; }
}
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
}
When I connect to the DB and call a sproc, the CustomerTypeHandler Parse method is never called and my CreditAccount object is populated with the AccountId only. The Customer object is null.
I am calling it as follows:
public async Task<CreditAccount> GetCreditAccount(int accountId)
{
var sql = "MY PROC NAME HERE";
var parameters = new DynamicParameters();
parameters.Add("#AccountId", accountId);
SqlMapper.AddTypeHandler(new CustomerTypeHandler());
using (IDbConnection connection = Connection)
{
connection.Open();
var account = await connection.QueryFirstAsync<CreditAccount>(sql, parameters, commandType: CommandType.StoredProcedure);
return account;
}
}
}
I placed a breakpoint in the Parse method and it is never called.
The database connection works, and I am getting the AccountId.
My environment;
.NET Core 2.2
Dapper 1.50.5
The code is simple enough. I get not exceptions. Any ideas?
A year has passed and now there is no this error in Dapper 2.0.30.
I checked it on jsonb columns in Postgres.
using Dapper;
using Newtonsoft.Json;
using Npgsql;
using System;
using System.Data;
public class CreditAccount
{
public int AccountId { get; set; }
public Customer Customer { get; set; }
}
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
}
public class CustomerJsonObjectTypeHandler : SqlMapper.TypeHandler<Customer>
{
public override void SetValue(IDbDataParameter parameter, Customer value)
{
parameter.Value = (value == null)
? (object)DBNull.Value
: JsonConvert.SerializeObject(value);
parameter.DbType = DbType.String;
}
public override Customer Parse(object value)
{
return JsonConvert.DeserializeObject<Customer>(value.ToString());
}
}
Example using this classes - all work fine.
static void Main(string[] args)
{
using (var connection = GetDefaultConnection())
{
connection.Open();
var customer = new Customer
{
FirstName = "Gaday",
LastName = "Ivanova",
MiddleName = "Petrovich"
};
var jsonData = JsonConvert.SerializeObject(customer);
var strQuery = $"SELECT 10500 as AccountId,'{jsonData}'::jsonb as Customer";
SqlMapper.AddTypeHandler(new CustomerJsonObjectTypeHandler());
try
{
var data = connection.QueryFirst<CreditAccount>(strQuery);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

Dapper: How to return selected columns?

public List<Customer> getCustomer()
{
using (IDbConnection con=DapperConnection())
{
string sql = "Select * from Customer";
return con.Query<Customer>(sql).Select(x => new { x.Id, x.LastName })
.ToList();
}
}
class Customer
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set;}
}
Does anyone know how to return specific columns using dapper? What I am trying to achieve is to return just the Id and LastName as List so that I can bind them to my controls.
Unsure exactly what you mean but surely you should return the customer object instead of an anonymous type, or at least make a smaller version of the customer object to be used by the controls
public List<Customer> getCustomers()
{
using (IDbConnection con = DapperConnection())
{
string sql = "Select * from Customer";
return con.Query<Customer>(sql).ToList();
}
}
Or if you dont like the overhead of returning the full customer object
public List<CustomerBase> getCustomers()
{
using (IDbConnection con = DapperConnection())
{
string sql = "Select * from Customer";
return con.Query<CustomerBase>(sql).ToList();
}
}
public class CustomerBase
{
public string Id { get; set; }
public string LastName { get; set; }
}
public class Customer: CustomerBase
{
public string FirstName { get; set; }
//Other props...
}

Powerpacks DataRepeater Control - Image not getting loaded in picture box

I have a winform powerpacks datareapter control having a picture box. This is the code snippet from the classes.
DisplaySystemUsersControl.Designer.cs
this.picBoxUserImage.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.picBoxUserImage.DataBindings.Add(new System.Windows.Forms.Binding("Image", this.UserBindingSource, "User_Image", true));
this.picBoxUserImage.Location = new System.Drawing.Point(3, 3);
this.picBoxUserImage.Name = "picBoxUserImage";
this.picBoxUserImage.Size = new System.Drawing.Size(100, 93);
this.picBoxUserImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.picBoxUserImage.TabIndex = 0;
this.picBoxUserImage.TabStop = false;
this.picBoxUserImage.Click += new System.EventHandler(this.picBoxUserImage_Click);
DisplaySystemUsersControl.cs
public DisplaySystemUsersControl()
{
InitializeComponent();
this.dataRepeaterAccounts.DataSource = this.UserBindingSource;
LoadAccountData();
}
private void LoadAccountData()
{
SystemUserBusinessClass oSystemUserBusinessClass = new SystemUserBusinessClass();
List<SystemUserEntity_Only_For_UI_Binding> obj = oSystemUserBusinessClass.GetSystemUsersForUI();
BindingSource tempUserBindingSource = (BindingSource)dataRepeaterAccounts.DataSource;
obj.ForEach(oSystemUserEntity_Only_For_UI_Binding => tempUserBindingSource.Add(oSystemUserEntity_Only_For_UI_Binding));
}
SystemUserEntity_Only_For_UI_Binding.cs
public class SystemUserEntity_Only_For_UI_Binding
{
public string User_Id { get; set; }
public string User_Name { get; set; }
public byte[] User_Image { get; set; }
}
User ID and User name is getting loaded. But Image is not getting loaded. SystemUserEntity_Only_For_UI_Binding.User_Image() is holding the image byte array.
Can anybody please tell me what is going wrong?
Your class should look something like this:
public class SystemUserEntity_Only_For_UI_Binding
{
public string User_Id { get; set; }
public string User_Name { get; set; }
public Image User_Image { get; set; }
}
The byte array needs to be translated into an image somewhere in your code:
using (MemoryStream ms = new MemoryStream(imgBytes)) {
this.User_Image = Image.FromStream(ms);
}
public void BindRepeater (DataSet dsObj)
{
pictureBox1.DataBindings.Clear();
pictureBox1.DataBindings.Add("ImageLocation", dt, "Photo");
dataRepeater1.DataSource = dsObj;
}

Resources