PTWin\ProjectEdit.cs: ResourceId.Visible - trouble and solutions

PTWin\ProjectEdit.cs: ResourceId.Visible - trouble and solutions

Old forum URL: forums.lhotka.net/forums/t/4118.aspx


so24wo posted on Friday, January 04, 2008

This issue is addressed at least to:
PTWin\ProjectEdit.cs, up to rev.1900 (current)
.Net 2.0


Recall that we set the ResourceId.Visible property to false at design time
(see Chapter 9, Page 502, "Expert C# 2005 Business Objects, Second Edition").

But there is a small trouble.

The ResourceId.Visible property is switched to true when we initialize
projectBindingSource.DataSource with _project in BindUI().

    private void BindUI()
    {
      _project.BeginEdit();
      this.projectBindingSource.DataSource = _project;
// ResourceId.Visible switched to true here.
    }

Anybody can see this just comparing two pictures in the book:
Figure 9-14 (p.498) shows the ResourceId column was hidden at design time.
But this column is visible on the figure 9-20 (p.503) when the programm shows the grid to a user.


First my idea was simply hide this column just after the datasource was assigned:

    private void BindUI()
    {
      _project.BeginEdit();
      this.projectBindingSource.DataSource = _project;
     
      if ( ResourceId.Visible )
        ResourceId.Visible = false; // hide the ResourceId column

    }


But are there any other ideas instead of checking each grid showed to users
and comparing them with the design requirements?


Yes. 

This switching happens only before datagridview is completely initialized.

And all we needs is just move binding code from the ProjectEdit() constructor to
the control load event handler. When this event is fired all grids on the control
are initialized already and our assigns to the projectBindingSource.DataSource
will not change the ResourcesDataGridView layout.

So the code:

    public ProjectEdit(Project project)
    {
      InitializeComponent();

      // store object reference
      _project = project;

      //// set up binding
      //this.roleListBindingSource.DataSource = RoleList.GetList();

      //BindUI();

      //// check authorization
      //ApplyAuthorizationRules();

    }

    private void ProjectEdit_Load( object sender, EventArgs e )
    {
     
// set up binding
      this.roleListBindingSource.DataSource = RoleList.GetList();

      BindUI();

      // check authorization
      ApplyAuthorizationRules();
    }

    private void BindUI()
    {
      _project.BeginEdit();
      this.projectBindingSource.DataSource = _project;
    }

and the RerourceId column stay invisible.


---
Regards,
Oleg

RockfordLhotka replied on Friday, January 04, 2008

Nice! Thank you for sharing the solution to this problem!

so24wo replied on Saturday, January 05, 2008

After I posted the previous message I begin reread RolesEdit.cs to prepare next
article about RolesEdit.SaveButton_Click() and I was surprised.

The technique described here is successfully used in
RolesEdit.RolesEdit_Load().

Nice. Isn't it?

---
Regards,
Oleg

stefan replied on Monday, January 07, 2008

I have a form with a tab control on it, which has a datagridview control on each of its 4 tabpages.
Each datagridview ist bound to a different bindingsource control. All these bind to a different child collection of a 'master'-bindingsource.

Your solution only works for the datagridview on the first tabpage...

Anybody any ideas?

Stefan

so24wo replied on Tuesday, January 08, 2008

stefan:
I have a form with a tab control on it, which has a datagridview control on each of its 4 tabpages.
Each datagridview ist bound to a different bindingsource control. All these bind to a different child collection of a 'master'-bindingsource.

Your solution only works for the datagridview on the first tabpage...

Anybody any ideas?

Stefan

You are right. I reproduced this also.

There is one another solution.

To initialize some internal bits of your datagridviews you can use the DrawToBitmap() method.
And with this method you don't need to wait for the load event. All code can be placed inside the constructor.

So my code looks like:

    public UserControl1(Project project)
    {
      InitializeComponent();

      // store object reference
      _project = project;

      // Initialize datagridviews:
      resourcesDataGridView.DrawToBitmap( new Bitmap(1,1), new Rectangle(0,0,1,1));
      resourcesDataGridView1.DrawToBitmap( new Bitmap(1,1), new Rectangle(0,0,1,1));
      resourcesDataGridView2.DrawToBitmap( new Bitmap(1,1), new Rectangle(0,0,1,1));
      resourcesDataGridView3.DrawToBitmap( new Bitmap(1,1), new Rectangle(0,0,1,1));

      // set up binding
      this.roleListBindingSource.DataSource = RoleList.GetList();

      BindUI();

      // check authorization
      ApplyAuthorizationRules();

    }


I've checked this idea over the WinPart-based control and over the Form-based window with an ErrorProvider on it.
This works well.


---
Regards,
Oleg

stefan replied on Thursday, January 10, 2008

I have found one solution that works.

The issue is related to the way a TabControl creates its child controls...
and databinding only works with controls that have already been created!
The background is explained here.

In Form_Load you have to put:

    Me.TabPage2.Show()
    Me.TabPage2.Hide()
    Me.TabPage3.Show()
    Me.TabPage3.Hide()
    Me.TabPage4.Show()
    Me.TabPage4.Hide()
    ...
before any databinding related code.
This forces the creation of the DataGridView controls and results in the correct presentation of the columns as set in the designer.

Stefan

Copyright (c) Marimer LLC