Error CS0122 'Reservation2.comboBox_Name_2' is inaccessible due to its protection level

Lin100

Well-known member
Joined
Dec 12, 2022
Messages
69
Programming Experience
10+
I have one error on the code as shown below. R2.comboBox_Name_2 is in form Reservation2.
R2.comboBox_Name_2.Text = this.dataGridView2.CurrentRow.Cells[0].Value.ToString(); <<---- Error CS0122 on line 13
Error CS0122 'Reservation2.comboBox_Name_2' is inaccessible due to its protection level


T1.Property_Name is in form Tenant and there is no problem with it. Line 19
R1.Property_Name is in form Reservation1 and there is no problem with it. Line 26


Code for Form Unit_2.CS:
private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
  {
     string Apartment_Status;
     DateTime Date_Reserved = DateTime.Today;

     object value = this.dataGridView2.CurrentRow.Cells[7].Value.ToString();
     Apartment_Status = value.ToString();
 
     switch (Apartment_Status)
       {
         case "Reserved":
           Reservation2 R2 = new Reservation2();
           R2.comboBox_Name_2.Text = this.dataGridView2.CurrentRow.Cells[0].Value.ToString();
           R2.Show();
         break;

         case "Occupied":
           Tenant T1 = new Tenant();
           T1.Property_Name.Text = this.dataGridView2.CurrentRow.Cells[0].Value.ToString();
           T1.Unit_Number.Text = this.dataGridView2.CurrentRow.Cells[1].Value.ToString();
           T1.Show();
         break;

         case "Vacant":
           Reservation1 R1 = new Reservation1();
           R1.Property_Name.Text = this.dataGridView2.CurrentRow.Cells[0].Value.ToString();
           R1.Unit_Number.Text = this.dataGridView2.CurrentRow.Cells[1].Value.ToString();

           string Property_Name = R1.Property_Name.Text;
           string Property_ID = Obtain_Property_ID(Property_Name);

           R1.Reservation_Number.Text = "R-" + Property_ID + "-" + R1.Unit_Number.Text + "-" + Date_Reserved.ToString("MM-dd-yyyy");

           R1.Date_Reserved.Text = Date_Reserved.ToString("MM/dd/yyyy");
           R1.Date_Moved_In_Planned.Text = DateTime.Today.AddDays(30).ToString("MM/dd/yyyy");
           R1.Lease_Months.Text = "12";
           R1.Reservation_Cancelled.Text = "No";
           R1.Show();
         break;

         default:
         break;
       }

     string Obtain_Property_ID(string Property_Name)
     {
        using (var con = new OleDbConnection())
        using (var cmd = new OleDbCommand())
        {
           con.ConnectionString = ConfigurationManager.ConnectionStrings["Apartment_Management.Properties.Settings.AMS_2007ConnectionString"].ToString();
           con.Open();

           cmd.CommandText = "SELECT Property_ID FROM Property WHERE Property_Name = @pn ";
           cmd.Parameters.AddWithValue("@pn", Property_Name);

           cmd.Connection = con;
           return (string)cmd.ExecuteScalar();
        }
      }
    }
 
When you add a control to a form, the designer generates a field and that field is declared private. Obviously you cannot access private members from outside the class. You could change the access modifier to public but that would be a mistake. Your two best options are:
  1. If the value is required by the form, add a parameter to the constructor. You then pass the data when you create form and you can set the control property inside the constructor.
  2. If the value is not required, add a property to the form. You can then set the property after creating the form (or when you create it, with an object initialiser) and you can set the control property inside the property setter. As you're probably only going to be setting the value, you can omit the property getter or use a method instead of a property.
 
What about the two issue below ?
How is it Tenant and Reservation1 has no problem seeing the code reference
a text box on a different form ?

T1.Property_Name is in form Tenant and there is no problem with it. Line 19
R1.Property_Name is in form Reservation1 and there is no problem with it.
Line 26
 
Look at your old thread post:

Reservation1.Designer.cs has a mix of public and private modifiers for your controls. Compare that to your Reservation2.Designer.cs that has all controls marked as private.
 
Here is what I did to bring the value from Unit_2.cs to Reservation2.cs
Line 5 of Unit_2.cs and Line 15 of Reservation2.cs. This looks like
the simplest with least amount of code.

jmcilhinney did suggest add a parameter to the constructor.​

If this is a better method, then please put the exact ode here.

Partial code from form Unit_2.CS:
switch (Apartment_Status)
    {
            case "Reserved":
              Reservation2 R2 = new Reservation2();
              R2.Property_Name_Text.Text = this.dataGridView2.CurrentRow.Cells[0].Value.ToString();
              R2.Show();
            break;

            default:
            break;
    }

code from Reservation2.cs:
      private void comboBox_property_name()
      {
         OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\AMS_2007.accdb");
         OleDbDataAdapter da = new OleDbDataAdapter("SELECT Property.Property_Name, Property.Property_ID, Property.Property_Phone, Property.Property_Manager FROM Property", con);
         con.Open();
         DataSet dt = new DataSet();
         da.Fill(dt, "Property_Name");

         comboBox_Name_2.DataSource = dt.Tables["Property_Name"];
         comboBox_Name_2.DisplayMember = "Property_Name";
         comboBox_Name_2.ValueMember = "Property_ID";

         // The comboBox_Name_2 display the Property_Name_Text whose value
         // originated from code in Unit_2.CS
         comboBox_Name_2.Text = Property_Name_Text.Text;
           
         con.Close();
      }
 
Yes it is the simplest, but also breaks The Law of Demeter. If you must expose a property, expose a property that is of type string, not of type TextBox or ComboBox.
 
1) I declared Test_Property_Name as public string underneath the method
public partial class Unit_2 : Form in UNIT_2.CS -----> LINE 6

2) I assigned Test_Property_Name a value in UNIT_2.CS ----> LINE 19

3) I used the variable Test_Property_Name in RESERVATION2.CS and it gives
me an error. ----> LINE 14
Error CS0103 The name 'Test_Property_Name' does not exist in the current context

Partial code for UNIT_2.CS:
namespace Apartment_Management
{
    public partial class Unit_2 : Form
   {

      public string Test_Property_Name = "";    ----> Declare variable

      public Unit_2()
      {
         InitializeComponent();
      }

switch (Apartment_Status)
  {
      case "Reserved":
        Reservation2 R2 = new Reservation2();
       
        //Assign a value here
        Test_Property_Name = this.dataGridView2.CurrentRow.Cells[0].Value.ToString();
       
        R2.Show();
      break;

      default:
      break;
    }

partial code for Reservation2.CS:
      private void comboBox_property_name()
      {
         OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\AMS_2007.accdb");
         OleDbDataAdapter da = new OleDbDataAdapter("SELECT Property.Property_Name, Property.Property_ID, Property.Property_Phone, Property.Property_Manager FROM Property", con);
         con.Open();
         DataSet dt = new DataSet();
         da.Fill(dt, "Property_Name");

         comboBox_Name_2.DataSource = dt.Tables["Property_Name"];

         comboBox_Name_2.DisplayMember = "Property_Name";
         comboBox_Name_2.ValueMember = "Property_ID";

         comboBox_Name_2.Text = Test_Property_Name.Text;    --->>>>    ERROR  HERE

         con.Close();
      }
 
Your Test_Property_Name on line 6 of Unit_2.cs is not a property. It's a field:


As compared to a property:


I am surprised that your Unit_2.cs even compiles. As far as I know, you can't have a switch statement outside of a method.

Anyway, your error on line 19 is due to scoping rules. You declared Test_Property_Name in your Unit_2 class, not your Reservation2 class. In other words, the Test_Property_Name is not in the same scope, or as the compiler puts it "not in the current context".
 
The logic behind what I did is this:
I have declared Test_Property_Name in Unit_2.cs so that I can assign a value based on
where the mouse is clicked in the DataGridView in Unit_2 form. Since I declared it as public I would think that Reservation2.cs would know of its existence.

It is like when you are in MS Access database and you declare a variable Test_Property_Name as public in a code module. Test_Property_Name can be used in any where within that database.
 
Unfortunately, C# is not MS Access. C# doesn't have any global variables.

The code in Reservation2 can access public data from Unit_2, as long as it has the instance of Unit_2 to talk to.

Go back to what the recommendation was above: make the property in on the form that needs it. Reservation2 needs it. Therefore, it should be the one that declares a property.
 

Latest posts

Back
Top Bottom