1

I will try autoload textbox value if I change my combobox index but dont understand if I load my form I receive this error?

enter image description here

I handle my null and if I ignore this line everything is fine !

this is my form


enter image description here

this is my repositories

AreaRepository

public string GetAreaNamebyAreaID(int areaID)
{
    var result = db.btbArea.SingleOrDefault(g => g.AreaID == areaID);

    if (result == null)
        return string.Empty;

    return result.AreaName;
}

HowzehRepository

public string GetHowzehNamebyHoezehID(int howzehID)
{
    var result = db.btbHowzeh.SingleOrDefault(g => g.HowzehID == howzehID);
    if (result == null)
        return string.Empty;

    return result.HowzehName;
}

PaygahRepository

public string GetPaygahNamebyPaygahID(int paygahID)
{
    var result = db.btbPaygah.SingleOrDefault(g => g.PaygahID == paygahID);
    if (result == null)
        return string.Empty;

    return result.PaygahName;
}

I will try load my textbox value if I change my combobox index

private void frmAreasManage_Load(object sender, EventArgs e)
{
    //Load AreaComboBox Source from AreaTable
    using (UnitOfWork db = new UnitOfWork())
    { 
        cmbAreaNumber.DataSource = db.AreaRepository.Get();
        cmbAreaNumber.DisplayMember = "AreaNumber";
        cmbAreaNumber.ValueMember = "AreaID";
    }
}

private void cmbAreaNumber_SelectedIndexChanged(object sender, EventArgs e)
{
    string selectedValue = cmbAreaNumber.SelectedValue.ToString();
    using (UnitOfWork db = new UnitOfWork())
        if (!string.IsNullOrEmpty(selectedValue))
        {
            {
                //Load HowzehhComboBox From HowzehTable Filter By AreaID
                cmbHowzehNumber.DataSource = db.HowzehRepository.GetNameIDByFilter(selectedValue);

                cmbHowzehNumber.DisplayMember = "HowzehNumber";
                cmbHowzehNumber.ValueMember = "HowzehID";

                //Get AreaName from AreaTable Filter By AreaID
                txtAreaName.Text = db.AreaRepository.GetAreaNamebyAreaID(Convert.ToInt32(selectedValue));
            }
        }
}

private void cmbHowzehNumber_SelectedIndexChanged(object sender, EventArgs e)
{
    string selectedValue = cmbHowzehNumber.SelectedValue.ToString();
    using (UnitOfWork db = new UnitOfWork())
        if (!string.IsNullOrEmpty(selectedValue))
        {
            //Load PaygahComboBox From PaygahTable Filter By HowzehID
            cmbPaygahNumber.DataSource = db.PaygahRepository.GetNameIDByFilter(selectedValue);

            cmbPaygahNumber.DisplayMember = "PaygahNumber";
            cmbPaygahNumber.ValueMember = "PaygahID";
            //Get HowzehName from HowzehTable Filter By HowzehID
            txtHowzehName.Text = db.HowzehRepository.GetHowzehNamebyHoezehID(Convert.ToInt32(selectedValue));
        }
}

private void cmbPaygahNumber_SelectedIndexChanged(object sender, EventArgs e)
{
    using (UnitOfWork db = new UnitOfWork())
    {
        //Get HowzehName from HowzehTable Filter By HowzehID
        txtPaygahName.Text = db.PaygahRepository.GetPaygahNamebyPaygahID(Convert.ToInt32(selectedValue));
    }
}
Iliar Turdushev
  • 4,935
  • 1
  • 10
  • 23
  • In the screenshot the `selectedValue` is not a number. use `if(int.TryParse(selectedValue, out int res)){...}` instead of `if (!string.IsNullOrEmpty(selectedValue))`. Also make sure `cmbAreaNumber.Items` are valid numbers. – Hamid Reza Mohammadi May 12 '20 at 01:28
  • The debugger information shows that `cmbAreaNumber.SelectedValue` is not a number, but is instead a `System.Data.Entity.DynamicProxies`. This is likely to relate to the following issue: [Why is EF returning a proxy class instead of the actual entity?](https://stackoverflow.com/questions/9501471/why-is-ef-returning-a-proxy-class-instead-of-the-actual-entity) – Ross Gurbutt May 12 '20 at 01:35
  • @HamidRezaMohammadi if i ignore this line //txtAreaName.Text = db.AreaRepository.GetAreaNamebyAreaID(Convert.ToInt32(selectedValue)); other line work correct translate to farsi hamidreza jan man in line ro ke commend mikonam hamechi khoobe yani hata vaghti form load mishe error nadaram ( yani age iradi daram tooye load form man etefagh miogte - hes mikonam tooye load form bayad ye kari konam ke combobox man kolan null bashe ke changeindex ejra nashe ta vaghti ke yeky entekhabesh kone ) ama nemidoonam chetori man taze shoro kardam – Ali Zangeneh May 12 '20 at 01:58
  • I'm so sorry for my first comment, I have a mistake and didn't pay attention to the actual data type. As Ross suggestion it's not a number, but is instead a `System.Data.Entity.DynamicProxies`. – Hamid Reza Mohammadi May 12 '20 at 02:54
  • @RossGurbutt i turn off Lazy Loading Enabled and use set Configuration.ProxyCreationEnabled = false; but my problem not solved – Ali Zangeneh May 12 '20 at 04:28
  • Try to replace problem line `txtAreaName.Text = db.AreaRepository.GetAreaNamebyAreaID(Convert.ToInt32(selectedValue));` with the next one: `txtAreaName.Text = db.AreaRepository.GetAreaNamebyAreaID(((Area)cmbAreaNumber.SelectedValue).AreaID);`. – Iliar Turdushev May 12 '20 at 06:33
  • I supposed that *Area* is the type of the objects returned by the method *db.AreaRepository.Get()*. This method is used to set *DataSource* of the *cmbAreaNumber*. Instead of the *Area* you should write actual name of the of the objects returned by the method *db.AreaRepository.Get()*. – Iliar Turdushev May 12 '20 at 12:59
  • From screenshot I found out that required type is *btbArea*. Try to replace the word *Area* with *btbArea*. – Iliar Turdushev May 12 '20 at 13:06
  • @IliarTurdushev i use this code txtAreaName.Text = db.AreaRepository.GetAreaNamebyAreaID(((btbArea)cmbAreaNumber.SelectedValue).AreaID); my problem solved if i open form ( first load ) but if i change combobox value i receive this error ( System.InvalidCastException: 'Unable to cast object of type 'System.Int32' to type 'Gim.DataLayer.btbArea'.' ) – Ali Zangeneh May 12 '20 at 15:16

1 Answers1

0

TL;DR

To fix your problem make the next changes in the method frmAreasManage_Load:

private void frmAreasManage_Load(object sender, EventArgs e)
{
    //Load AreaComboBox Source from AreaTable
    using (UnitOfWork db = new UnitOfWork())
    { 
        // At first assign properties DisplayMember and ValueMember.
        cmbAreaNumber.DisplayMember = "AreaNumber";
        cmbAreaNumber.ValueMember = "AreaID";

        // And then assign DataSource property of the cmbAreaNumber.
        cmbAreaNumber.DataSource = db.AreaRepository.Get();
    }
}

Explanation

Why do we need to assign ValueMember before DataSource property?

When we assign DataSource property the first item of the assigned collection becomes SelectedValue of the ComboBox. This triggers ComboBox.SelectedIndexChanged event.

If we assign DataSource before ValueMember (and therefore ValueMember = null) then CombobBox.SelectedValue is the first item of the collection itself. In your case SelectedValue is an object of type btbArea. Therefore when I asked you to use the next code in the cmbAreaNumber_SelectedIndexChanged handler

txtAreaName.Text = db.AreaRepository.GetAreaNamebyAreaID(((btbArea) cmbAreaNumber.SelectedValue).AreaID);

it fixed the problem for first load. But then you got System.InvalidCastException: 'Unable to cast object of type 'System.Int32' to type 'Gim.DataLayer.btbArea'. This error occured because then ValueMember property was assigned to the value AreaID and from that moment ComboBox.SelectedValue was the value of the property int AreaID of the btbArea.

If we assign ValueMember = "AreaID" and then DataSource then whenever ComboBox.SelectedIndexChanged event is raised, SelectedValue is the value of the property AreaID. And therefore to prevent SelectedValue of being an object of type btbArea (situation when ValueMember = null) we must at first assign ValueMember and then DataSource.

Iliar Turdushev
  • 4,935
  • 1
  • 10
  • 23