This is my class:
class EmpDetails
{
private string _EmpName;
private int _EmpID;
private string _EmpDepartment;
private string _EmpPosition;
public string EmpName
{
get
{
return _EmpName;
}
set
{
_EmpName = value;
}
}
public int EmpID
{
get
{
return _EmpID;
}
set
{
_EmpID = value;
}
}
public string EmpDepartment
{
get
{
return _EmpDepartment;
}
set
{
_EmpDepartment = value;
}
}
public string EmpPosition
{
get
{
return _EmpPosition;
}
set
{
_EmpPosition = value;
}
}
}
}
Following is my form:
public partial class Form1 : Form
{
EmpDetails d = new EmpDetails();
public Form1()
{
InitializeComponent();
}
private void btnSet_Click(object sender, EventArgs e)
{
d.EmpName = txtName.Text;
d.EmpID = Convert.ToInt32(txtID.Text);
d.EmpDepartment = txtDepartment.Text;
d.EmpPosition = txtPosition.Text;
}
private void btnClear_Click(object sender, EventArgs e)
{
txtName.Clear();
txtID.Clear();
txtDepartment.Clear();
txtPosition.Clear();
}
private void btnGet_Click(object sender, EventArgs e)
{
txtName.Text = d.EmpName;
txtID.Text = Convert.ToString(d.EmpID);
txtDepartment.Text = d.EmpDepartment;
txtPosition.Text = d.EmpPosition;
}
}
}
I am setting the values using text boxes in form so that the values go
in to properties I have created in class.
I'm getting error like: EncapsulationAssignmentCSharp.EmpDetails
does not contain a definition for GetEmpName and no extension
method GetEmpName accepting a first argument of type
EncapsulationAssignmentCSharp.EmpDetails could be found (are you
missing a using directive or an assembly reference?
I am guessing that I have to create a constructor with parameters and
set the values using keyword this, but I'm not sure how to pass the
values to the constructor. Please help me I am not very good with
programming.
Debug and run the code and check whether your code is calling GetEmpName
Related
I have the class TestClass that has ToString overriden (it returns Name field).
I have instances of TestClass added into ListBox and at certain point I need to change Name of one of this instances, how then I can refresh it's text in ListBox?
using System;
using System.Windows.Forms;
namespace TestListBox
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
listBox1.Items.Add(new TestClass("asd"));
listBox1.Items.Add(new TestClass("dsa"));
listBox1.Items.Add(new TestClass("wqe"));
listBox1.Items.Add(new TestClass("ewq"));
}
private void button1_Click(object sender, EventArgs e)
{
((TestClass)listBox1.Items[0]).Name = "123";
listBox1.Refresh(); // doesn't help
listBox1.Update(); // same of course
}
}
public class TestClass
{
public string Name;
public TestClass(string name)
{
this.Name = name;
}
public override string ToString()
{
return this.Name;
}
}
}
try
listBox1.Items[0] = listBox1.Items[0];
I have encountered this same issue and tried all sorts of different ways to tr y to get the displayed text of an item to actually reflect the underlying item value.
After going through all the available properties I found this to be the simplest.
lbGroupList.DrawMode = DrawMode.OwnerDrawFixed;
lbGroupList.DrawMode = DrawMode.Normal;
It triggers the appropriate events within the control to update the displayed text.
Your Testclass needs to implement INotifyPropertyChanged
public class TestClass : INotifyPropertyChanged
{
string _name;
public string Name
{
get { return _name;}
set
{
_name = value;
_notifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void _notifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public TestClass(string name)
{
this.Name = name;
}
public override string ToString()
{
return this.Name;
}
}
However this only works if you use Columns that do not rely on the ToString() but bind the property Name
This can be done by altering your code:
somewhere in class declare
BindingList<TestClass> _dataSource = new BindingList<TestClass>();
In initializeComponent write
listBox1.DataSource = _dataSource;
Then do all operations on _dataSource instead of Listbox.
You could use a BindingList:
items = new BindingList<TestClass>( );
listBox1.DataSource = items;
listBox1.DisplayMember = "_Name";
Then to refresh the list call:
items.ResetBindings( );
edit: Also don't forget to create a get Property for Name
public string _Name
{
get { return Name; }
set { Name= value; }
}
I use the following code:
public static void RefreshItemAt (ListBox listBox, int itemIndex)
{
if (itemIndex >= 0)
{
Rectangle itemRect = listBox.GetItemRectangle(itemIndex);
listBox.Invalidate(itemRect);
listBox.Update();
}
}
Well I was trying to assign global variable to read values from Check boxes and radio buttons but the values don't update when the selections are changed ! Where have I done wrong? Here's the code:
private void chkInMut_Checked(object sender, RoutedEventArgs e)
{
GlobalVar.Mutate = 1;
}
private void chkShwCal_Checked(object sender, RoutedEventArgs e)
{
GlobalVar.ShowCal = 1;
}
private void chkOutSol_Checked(object sender, RoutedEventArgs e)
{
GlobalVar.OutCal = 1;
}
}
public static class GlobalVar
{
static int _MaxMin, _MutVal, _CalShow, _CalOut;
/// <summary>
/// Access routine for global variable.
/// </summary>
public static int Extrema
{
get
{
return _MaxMin;
}
set
{
_MaxMin = value;
}
}
public static int Mutate
{
get
{
return _MutVal;
}
set
{
_MutVal = value;
}
}
public static int ShowCal
{
get
{
return _CalShow;
}
set
{
_CalShow = value;
}
}
public static int OutCal
{
get
{
return _CalOut;
}
set
{
_CalOut = value;
}
}
}
when I try to print the numbers using this test satement, the values returned are unexpected :
maxMin = GlobalVar.Extrema;
calShow = GlobalVar.ShowCal;
calOut = GlobalVar.OutCal;
IsMutble = GlobalVar.Mutate;
txtOutput.Text += Convert.ToString("\nMaxima Minima"+maxMin+"\n"+"Show Cal : "+calShow+"\n"+"Output Cal :"+calOut+"\n"+"Mutate : "+IsMutble+"\n---------\n");
And when I check/un-check the boxes, the values are not updated as it should be. Where have I gone wrong?
Edit: Solved by adding Unchecked Parameter.
Probably you should write your event handlers like this
private void chkInMut_Checked(object sender, RoutedEventArgs e)
{
GlobalVar.Mutate = (chkInMut.IsChecked ? 1 : 0);
}
and so on .....
I think the problem is with your public static properties. for example try this:
public static int Extrema
{
get
{
return GlobalVar._MaxMin;
}
set
{
GlobalVar._MaxMin = value;
}
}
and do the same for all other properties.
Edit:
and why are you using this stucture? You can set your static class to be like this:
public static class GlobalVar
{
public static int Extrema;
public static int Mutate;
public static int ShowCal;
}
I have the a class in my application. It has been bound to winform textbox controls. But the textbox which is bound to BookingNo property, always shows zero (0). But i want the textbox keep empty. Is there any way to do it? Here is my code snippet.
public class Booking
{
private int pBookingNo;
private string pCustomerName;
private string pAddress;
public int BookingNo
{
get { return pBookingNo; }
set
{
if (!value.Equals(pBookingNo))
{
pBookingNo = value;
}
}
}
public string CustomerName
{
get { return pCustomerName; }
set
{
if (!value.Equals(pCustomerName))
{
pCustomerName = value;
}
}
}
public Booking() { }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
AddDataBindings();
}
private void AddDataBindings()
{
bsBooking.DataSource = typeof(Booking);
txtBookingNo.DataBindings.Add("Text", bsBooking, "BookingNo", true, DataSourceUpdateMode.OnPropertyChanged, null, "G", GlobalVariables.CurrentCultureInfo);
txtCustomerName.DataBindings.Add("Text", bsBooking, "CustomerName");
}
}
The default value of an Integer is 0, so you have to wrap it into some other object, which supports values other than 0, like
public int? BookingNo { get; set; }
You can use Nullable Type
public int? pBookingNo
{
get;
set;
}
Link : http://msdn.microsoft.com/fr-fr/library/1t3y8s4s(v=vs.80).aspx
You could use custom formatting for the binding by adding a handler to the Format event (http://msdn.microsoft.com/en-us/library/system.windows.forms.binding.format.aspx) and return an empty string when the value is zero. But you wouldn't be able to tell whether the value is actually zero or it just hasn't been set already, in which case using the int? approach suggested by #Grumbler85 is better.
what´s about:
textBox1.BindingContextChanged += new EventHandler(BindingContext_Changed);
private void BindingContext_Changed(object sender, EventArgs e)
{
TextBox txtBox = (TextBox)sender;
if (txtBox.Text == "0"){
txtBox.Text = "";
}
}
don´t know if it works, just an idea.
I have a class that implements the INotifyPropertyChanged interface.
If I create a new instance of the object, the PropertyChanged event gets set after I retrieve a value from it.
Example:
MyItem itm = new MyItem(); //MyItem.PropertyChanged == null
string test = itm.Value; //MyItem.PropertyChanged != null
If I assign itm the value of another MyItem, the PropertyChanged event remains null.
Example:
itm = (MyItem)cboMyItemsCombobox.SelectedItem; // Properties for itm change to the values
// of the selected item, but PropertyChanged
// == null
I believe the problem lies partially in my custom constructor for the class, but I'm not entirely sure.
The goal is to have a variable to hold data for a record, called mnuitm, that is bound to
3 textbox objects. When the text in a textbox changes, the change is made to the property in mnuitm. When the property in mnuitm is changed, the change is made in the textbox.
This works if I create a new MenuItem and assign the values individually, but does not work if I assign an already populated MenuItem to mnuitm.
Here is my actual code for (hopefully) more clearity on the issue.
public partial class frmMenuItems : Form
{
private class MenuItem : INotifyPropertyChanged
{
private Int32 mid;
private string txt;
private string url;
private string scp;
public MenuItem() { }
public MenuItem(Int32 id, string txt, string url, string scp)
{
ID = id;
Text = txt;
URL = url;
Script = scp;
}
public Int32 ID
{
get
{
return mid;
}
set
{
if (mid != value)
{
mid = value;
NotifyPropertyChanged("ID");
}
}
}
public string Text {
get
{
return txt;
}
set
{
if (txt != value)
{
txt = value;
NotifyPropertyChanged("Text");
}
}
}
public string URL {
get
{
return url;
}
set
{
if (url != value)
{
url = value;
NotifyPropertyChanged("URL");
}
}
}
public string Script {
get
{
return scp;
}
set
{
if (scp != value)
{
scp = value;
NotifyPropertyChanged("Script");
}
}
}
public void Clear()
{
ID = 0;
Text = "";
URL = "";
Script = "";
}
public override string ToString()
{
return Text;
}
private void NotifyPropertyChanged(string inf)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(inf));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
private MenuItem mnuitm;
private MySqlConnection sqlcon;
public frmMenuItems()
{
InitializeComponent();
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnCancel_Click(object sender, EventArgs e)
{
mnuitm.Clear();
}
private void frmMenuItems_Load(object sender, EventArgs e)
{
string constr = "server={0};uid={1};pwd={2};database={3};";
DBItem dbi = CountyDataManager.CountyData.DBConnection;
constr = string.Format(constr, [MyHost], [MyUsername], [MyPassword], [MyDatabase]);
sqlcon = new MySqlConnection(constr);
sqlcon.Open();
mnuitm = new MenuItem();
SetBindings();
RefreshList();
}
private void SetBindings()
{
txtMenuText.DataBindings.Clear();
txtURL.DataBindings.Clear();
txtScript.DataBindings.Clear();
txtMenuText.DataBindings.Add("Text", mnuitm, "Text");
txtURL.DataBindings.Add("Text", mnuitm, "URL");
txtScript.DataBindings.Add("Text", mnuitm, "Script");
}
private void RefreshList()
{
using (MySqlCommand cmd = new MySqlCommand("SELECT `menuid`,`menutext`,`url`,`script` FROM tblindexmenu ORDER BY `menutext`", sqlcon))
{
lstMenuItems.Items.Clear();
using (MySqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
lstMenuItems.Items.Add(new MenuItem(Int32.Parse(rdr[0].ToString()), rdr[1].ToString(),rdr[2].ToString(),rdr[3].ToString()));
}
}
}
}
private void frmMenuItems_FormClosing(object sender, FormClosingEventArgs e)
{
sqlcon.Close();
}
private void lstMenuItems_SelectedIndexChanged(object sender, EventArgs e)
{
if (lstMenuItems.SelectedIndex > -1)
{
mnuitm = (MenuItem)lstMenuItems.SelectedItem;
}
}
}
After receiving feedback, I made the following changes:
Added CopyFrom() to MenuItem
public void CopyFrom(MenuItem itm)
{
this.ID = itm.ID;
this.URL = itm.URL;
this.Text = itm.Text;
this.Script = itm.Script;
}
I then modified the SelectedIndexChanged code to use the new function
mnuitm.CopyFrom((MenuItem)lstMenuItems.SelectedItem);
This is by design. When you write
itm = (MyItem)cboMyItemsCombobox.SelectedItem;
you haven't changed any of the properties of the MenuItem itm used to point to, rather you changed the MenuItem itm points to.
One option for what you need is add a function to MenuItem that looks like
SetFromOtherMenuItem(MenuItem other)
{
this.Url = other.Url
//etc
}
Again, PropertyChanged means that a property on some instance has changed. In your case, only one of the variables pointing to that instance changed (to point to a different instance).
I have a gridview and, when a record is double-clicked, I want it to open up a new detail-view form for that particular record.
As an example, I have created a Customer class:
using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Collections;
namespace SyncTest
{
#region Customer Collection
public class CustomerCollection : BindingListView<Customer>
{
public CustomerCollection() : base()
{
}
public CustomerCollection(List<Customer> customers) : base(customers)
{
}
public CustomerCollection(DataTable dt)
{
foreach (DataRow oRow in dt.Rows)
{
Customer c = new Customer(oRow);
this.Add(c);
}
}
}
#endregion
public class Customer : INotifyPropertyChanged, IEditableObject, IDataErrorInfo
{
private string _CustomerID;
private string _CompanyName;
private string _ContactName;
private string _ContactTitle;
private string _OldCustomerID;
private string _OldCompanyName;
private string _OldContactName;
private string _OldContactTitle;
private bool _Editing;
private string _Error = string.Empty;
private EntityStateEnum _EntityState;
private Hashtable _PropErrors = new Hashtable();
public event PropertyChangedEventHandler PropertyChanged;
private void FirePropertyChangeNotification(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public Customer()
{
this.EntityState = EntityStateEnum.Unchanged;
}
public Customer(DataRow dr)
{
//Populates the business object item from a data row
this.CustomerID = dr["CustomerID"].ToString();
this.CompanyName = dr["CompanyName"].ToString();
this.ContactName = dr["ContactName"].ToString();
this.ContactTitle = dr["ContactTitle"].ToString();
this.EntityState = EntityStateEnum.Unchanged;
}
public string CustomerID
{
get
{
return _CustomerID;
}
set
{
_CustomerID = value;
FirePropertyChangeNotification("CustomerID");
}
}
public string CompanyName
{
get
{
return _CompanyName;
}
set
{
_CompanyName = value;
FirePropertyChangeNotification("CompanyName");
}
}
public string ContactName
{
get
{
return _ContactName;
}
set
{
_ContactName = value;
FirePropertyChangeNotification("ContactName");
}
}
public string ContactTitle
{
get
{
return _ContactTitle;
}
set
{
_ContactTitle = value;
FirePropertyChangeNotification("ContactTitle");
}
}
public Boolean IsDirty
{
get
{
return ((this.EntityState != EntityStateEnum.Unchanged) || (this.EntityState != EntityStateEnum.Deleted));
}
}
public enum EntityStateEnum
{
Unchanged,
Added,
Deleted,
Modified
}
void IEditableObject.BeginEdit()
{
if (!_Editing)
{
_OldCustomerID = _CustomerID;
_OldCompanyName = _CompanyName;
_OldContactName = _ContactName;
_OldContactTitle = _ContactTitle;
}
this.EntityState = EntityStateEnum.Modified;
_Editing = true;
}
void IEditableObject.CancelEdit()
{
if (_Editing)
{
_CustomerID = _OldCustomerID;
_CompanyName = _OldCompanyName;
_ContactName = _OldContactName;
_ContactTitle = _OldContactTitle;
}
this.EntityState = EntityStateEnum.Unchanged;
_Editing = false;
}
void IEditableObject.EndEdit()
{
_Editing = false;
}
public EntityStateEnum EntityState
{
get
{
return _EntityState;
}
set
{
_EntityState = value;
}
}
string IDataErrorInfo.Error
{
get
{
return _Error;
}
}
string IDataErrorInfo.this[string columnName]
{
get
{
return (string)_PropErrors[columnName];
}
}
private void DataStateChanged(EntityStateEnum dataState, string propertyName)
{
//Raise the event
if (PropertyChanged != null && propertyName != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
//If the state is deleted, mark it as deleted
if (dataState == EntityStateEnum.Deleted)
{
this.EntityState = dataState;
}
if (this.EntityState == EntityStateEnum.Unchanged)
{
this.EntityState = dataState;
}
}
}
}
Here is my the code for the double-click event:
private void customersDataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
Customer oCustomer = (Customer)customersBindingSource.CurrencyManager.List[customersBindingSource.CurrencyManager.Position];
CustomerForm oForm = new CustomerForm();
oForm.NewCustomer = oCustomer;
oForm.ShowDialog(this);
oForm.Dispose();
oForm = null;
}
Unfortunately, when this code runs, I receive an InvalidCastException error stating "Unable to cast object to type 'System.Data.DataRowView' to type 'SyncTest.Customer'".
This error occurs on the very first line of that event:
Customer oCustomer = (Customer)customersBindingSource.CurrencyManager.List[customersBindingSource.CurrencyManager.Position];
What am I doing wrong?... and what can I do to fix this? Any help is greatly appreciated.
Thanks!
EDIT:
Here is how the data is populated:
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'northwindDataSet.Customers' table. You can move, or remove it, as needed.
this.customersTableAdapter.Fill(this.northwindDataSet.Customers);
}
It looks like your object is of type System.Data.DataRowView, not Customer. Your code returns Dataset instead of objects that you are expecting. You need to modify the code that returns your objects.
How about using BindingSource.Current instead of CurrentManager? But from the looks of it, your data source is a DataSet.
private void customersDataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
DataGridView grid = (DataGridView) sender;
Customer customer = (Customer) grid.Rows[e.RowIndex].DataBoundItem;
}
Checks removed for brevity
Customer oCustomer = (Customer)
((DataRowView)customersBindingSource.Current).Row;
When you get the invalid cast as you have described it is due to the object is not the type you think it should be.
You can avoid the exception by using the as keyword.
Customer oCustomer = (Customer)customersBindingSource.CurrencyManager.List[customersBindingSource.CurrencyManager.Position];
becomes
Customer oCustomer = customersBindingSource.CurrencyManager.List[customersBindingSource.CurrencyManager.Position] as Customer;
If it is an invalid cast then oCustomer will be null.
Now if you are still getting the null then the object from List is not a Customer object. I would use the debugger to determine what the object is and how you would go about casting it to your Cusomter object.
You will never be able to convert directly to the Customer object because your error is
InvalidCastException error stating "Unable to cast object to type 'System.Data.DataRowView' to type 'SyncTest.Customer'". is giving you an DataRowView object. You need take the row and pull the values from the row.