WebPart - InPlace Custom Property editing

Bear with the formatting, this Blog engine is old and getting on my nerves.  Time for an upgrade after 8 yrs :P

Spent some time working on a WebPart implementation, where i wanted to edit the webpart in place instead of constantly clicking the glorious Edit WebPart for the WebPart object. So after some research, found a great article from MATHIEU DESMARAIS about the design patterns and logic flow. The main difference i had from his design, was i was prescribing the way the View/Edit Modes would be represented with the HTML syntax.

I will not bore you with the details of getting up to this point, as there are numerous amounts of posts out there. I will although focus on the details of how i took Mathieu's implementation and modified for a Static set. Some of the pitfalls i had, probably because his was on demand control creation and mine is predefined.

Notes to take mind of:
  • This Implementation is for a SQL Connection Webpart. As such, you will notice some SQL Connection familiars.
  • This is not a publicly available webpart, so i will not put ALL of the details of how this works, just the sections that pertain to the problem i got solved and the difference from Mathieu's implementation.
  • Currently this is Configure Once, and done. I am working on a Edit Configuration once it has been configured.


Design: WebPart.ascx:
1:  <asp:Panel ID="pnlView" Visible="true" runat="server">  
2:     <p id="txtContent" class="SQLTextContent reaonly" runat="server"></p>  
3:  </asp:Panel>  
4:  <asp:Panel ID="pnlEdit" Visible="false" runat="server">  
5:     <asp:Panel ID="pnlEditConfig" Visible="false" runat="server">  
6:        <p>WebPart has been configured</p>  
7:     </asp:Panel>  
8:     <asp:Panel ID="pnlEditNoConfig" Visible="true" runat="server">  
9:        <h3>SQLText WebPart Configuration:</h3>  
10:        <hr />  
11:        <table>  
12:           <tr>  
13:              <td>Server:</td>  
14:              <td><asp:TextBox ID="txtEditServer" runat="server" /></td>  
15:           </tr>  
16:           <tr>  
17:              <td>Database:</td>  
18:              <td><asp:TextBox ID="txtEditDatabase" runat="server" /></td>  
19:           </tr>  
20:           <tr>  
21:              <td>Schema:</td>  
22:              <td><asp:TextBox ID="txtEditSchema" runat="server" /></td>  
23:           </tr>  
24:           <tr>  
25:              <td>SProc:</td>  
26:              <td><asp:TextBox ID="txtEditSProc" runat="server" /></td>  
27:           </tr>  
28:           <tr style="border-top: 1px solid black">  
29:              <td><asp:Button ID="btnSubmit" Text="Submit" runat="server" /></td>  
30:              <td><asp:Button ID="btnClear" Text="Clear" runat="server" /></td>  
31:           </tr>  
32:        </table>  
33:     </asp:Panel>  
34:  </asp:Panel>  

Logic: WebPart.ascx.cs:
1:  public bool PropertiesSet () {  
2:  return ( !string.IsNullOrWhiteSpace( Server )   
3:  && !string.IsNullOrWhiteSpace( Database )   
4:  && !string.IsNullOrWhiteSpace( Schema )   
5:  && !string.IsNullOrWhiteSpace( SProc ) );   
6:  }  
7:  protected void Page_Load ( object sender , EventArgs e ) {  
8:     switch ( SPContext.Current.FormContext.FormMode ) {  
9:        case SPControlMode.Display:  
10:           pnlEdit.Visible = false;  
11:           pnlView.Visible = true;  
12:    
13:           //Make sure ALL properties have a value before trying to execute.  
14:           if ( !PropertiesSet() ) {  
15:              txtContent.InnerText = "WebPart Not Configured!";  
16:           } else {  
17:              txtContent.InnerText = "";  
18:              _conn = new SqlConnectionStringBuilder() {  
19:                 ...  
20:              }.ConnectionString;  
21:              _cmd = Schema + '.' + SProc;  
22:    
23:              var conn = new SqlConnection( _conn );  
24:              try {  
25:                 conn.Open();  
26:    
27:                 var cmd = new SqlCommand( _cmd , conn ) {  
28:                    CommandType = System.Data.CommandType.StoredProcedure  
29:                 };  
30:    
31:                 using ( var rdr = cmd.ExecuteReader() ) {  
32:                    while ( rdr.Read() ) {  
33:                       txtContent.InnerText += rdr[ "result" ] + Environment.NewLine;  
34:                    }  
35:                 }  
36:              } catch ( Exception ex ) {  
37:                 txtContent.InnerHtml += "Please take a ScreenShot!<br/>" +  
38:                 "Connection String: " + _conn + "<br/>" +  
39:                 "Unable to connect to the SQL Server.<br/>" +   
40:                 ex.Message + "<br/>" +   
41:                 ex.StackTrace;  
42:              } finally {  
43:                 conn.Close();  
44:              }  
45:           }  
46:           break;  
47:        case SPControlMode.Edit:  
48:           pnlView.Visible = false;  
49:           pnlEdit.Visible = true;  
50:    
51:           if ( PropertiesSet() ) {  
52:              pnlEditConfig.Visible = true;  
53:              pnlEditNoConfig.Visible = false;  
54:           } else {  
55:              pnlEditConfig.Visible = false;  
56:              pnlEditNoConfig.Visible = true;  
57:    
58:              if ( PropertiesSet() ) {  
59:                 txtEditServer.Text = Server;  
60:                 txtEditDatabase.Text = Database;  
61:                 txtEditSchema.Text = Schema;  
62:                 txtEditSProc.Text = SProc;  
63:              }  
64:    
65:              btnSubmit.Click += btnSubmit_Click;  
66:              btnClear.Click += btnClear_Click;  
67:           }  
68:    
69:           break;  
70:        //case SPControlMode.Invalid:  
71:        //   break;  
72:        //case SPControlMode.New:  
73:        //   break;  
74:        default:  
75:           break;  
76:     }  
77:    
78:  }  
79:    
80:  void btnClear_Click ( object sender , EventArgs e ) {  
81:     txtEditServer.Text = Server;  
82:     txtEditDatabase.Text = Database;  
83:     txtEditSchema.Text = Schema;  
84:     txtEditSProc.Text = SProc;  
85:  }  
86:    
87:  void btnSubmit_Click ( object sender , EventArgs e ) {  
88:     Server = txtEditServer.Text;  
89:     Database = txtEditDatabase.Text;  
90:     Schema = txtEditSchema.Text;  
91:     SProc = txtEditSProc.Text;  
92:    
93:     SetPersonalizationDirty();  
94:    
95:     pnlEditNoConfig.Visible = false;  
96:     pnlEditConfig.Visible = true;  
97:  }  

Now to the difference:
Mathieu had done most of his implementation in the CreateChildControls event for the control, whereas i preformatted mine in the HTML code of the control and then performed the logic evaluation in the Page_Load event handler.

One word of advise: DO NOT execute SetPersonalizationDirty from the WebPart class (like this.SetPersonalizationDirty()), cause for some reason the Page object will not recognize the execution.

Comments

Popular posts from this blog

SysInternals - BgInfo for ALL Users

JSON/AJAX Helpers

Acquiring List of controls - Classic JS