{"id":2425,"date":"2006-12-22T08:31:00","date_gmt":"2006-12-22T08:31:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/saving-the-telerik-radsplitterradpane-state\/"},"modified":"2016-07-28T10:48:59","modified_gmt":"2016-07-28T10:48:59","slug":"saving-the-telerik-radsplitterradpane-state","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/saving-the-telerik-radsplitterradpane-state\/","title":{"rendered":"Saving the Telerik RadSplitter\/RadPane State"},"content":{"rendered":"<p>Telerik makes UI controls for ASP.NET (and they are getting in Windows Forms controls too apparently) and they&#8217;ve done a great job.&#160;&#160; But, everything has it&#8217;s little quirks.&#160; I was&#160;working with the RadSplitter, a control that allows you to make collapsable \/ resizable panels on your webpage, when I ran across a little problem:&#160;persisting the state to a cookie.<\/p>\n<p>The cool thing about the RadSplitter is that you can resize \/ collapse a pane on the Client-Side, and the control will use JavaScript to update hidden fields on the page so it sends the new size and collapse state back to the server.&#160; We wanted to store that state in&#160;a cookie so when users closed the browser and returned, the resizable sections would retain their last size and collapse state. <\/p>\n<p>Here&#8217;s the issue:&#160; let&#8217;s say you have a pane that, by default, is 200px wide.&#160; You resize that pane on the client side to 350px, then collapse it (hide it).&#160; When you post the page back to the server, the pane reports its width as 0px.&#160; So, how do you save the width of an updated pane when it&#8217;s in a collapsed state?<\/p>\n<p>The answer lies in the ExpandedWidth property, which is an internal value to the control that is not publicly exposed.&#160; When a pane is collapsed, the ExpandedWidth property holds the width to which the pane should expand when expanded.&#160; ExpandedWidht is 0px when the pane is fully expanded.<\/p>\n<p>So, how do you get this value?&#160; All of the state information about a RadPane comes back in as a JavaScript Object Notation (<a href=\"http:\/\/www.json.org\/\">JSON<\/a>) string in a hidden field, which we can intercept and parse to acquire the ExpandedWidth property (or whatever other property you want to find).&#160; Here&#8217;s the code to save and load pane state for a RadPane in a RadSplitter:<\/p>\n<\/p>\n<p>\/\/\/ &lt;summary&gt;<br \/>\/\/\/ Regular expression used to parse JSON object info comming back from the Telerik splitter control. Telerik did not expose<br \/>\/\/\/ the expandedWidth property (which stores the width of the pane when it is collapsed) so you have to acquire it using a workaround<br \/>\/\/\/ &lt;\/summary&gt;<br \/>private static Regex SplitterRegex = new System.Text.RegularExpressions.Regex(&#8220;(?:&#8221;collapsed&#8221;:(?&lt;collapsed&gt;[^,\\}]*))(?:.*)(?:&#8221;expandedSize&#8221;:(?&lt;expandedSize&gt;[^,\\}]*))&#8221;, RegexOptions.IgnoreCase);<\/p>\n<p>\/\/\/ &lt;summary&gt;<br \/>\/\/\/ Saves splitter settings to the setting cookie<br \/>\/\/\/ &lt;\/summary&gt;<br \/>private void SaveSplitterSettings()<br \/>{<br \/>&#160;&#160;&#160; if (splitter != null)<br \/>&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; string splitterStateString = Page.Request.Form[paneLeft.ClientID];<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(!string.IsNullOrEmpty(splitterStateString))<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Match match = SplitterRegex.Match(splitterStateString);<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (match.Success)<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; try<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; bool collapsed = bool.Parse(match.Groups[1].Value);<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string width;<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (collapsed)<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; width = match.Groups[2].Value + &#8220;px&#8221;;<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; width = paneLeft.Width.ToString();<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; HttpCookie settingCookie = new HttpCookie(&#8220;iswSplitterSettings&#8221;);<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; settingCookie.Values.Add(&#8220;LW&#8221;, width);<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; settingCookie.Values.Add(&#8220;LS&#8221;, collapsed ? &#8220;1&#8221; : &#8220;0&#8221;);<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Page.Response.Cookies.Add(settingCookie);<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/Do nothing<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br \/>&#160;&#160;&#160; }<br \/>}<\/p>\n<p>\/\/\/ &lt;summary&gt;<br \/>\/\/\/ Loads splitter settings from the setting cookie<br \/>\/\/\/ &lt;\/summary&gt;<br \/>private void LoadSplitterSettings()<br \/>{<br \/>&#160;&#160;&#160; HttpCookie settingCookie = Page.Request.Cookies[&#8220;iswSplitterSettings&#8221;];<br \/>&#160;&#160;&#160; if (settingCookie != null)<br \/>&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; try<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; paneLeft.Width = new Unit(settingCookie.Values[&#8220;LW&#8221;].ToString());<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; paneLeft.InitiallyCollapsed = (bool)(settingCookie.Values[&#8220;LS&#8221;] == &#8220;1&#8221;);<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/Do nothing &#8211; allow the control to sort itself out<br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br \/>&#160;&#160;&#160; }<br \/>}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Telerik makes UI controls for ASP.NET (and they are getting in Windows Forms controls too apparently) and they&#8217;ve done a great job.&#160;&#160; But, everything has it&#8217;s little quirks.&#160; I was&#160;working with the RadSplitter, a control that allows you to make collapsable \/ resizable panels on your webpage, when I ran across a little problem:&#160;persisting the&#8230;&hellip;<\/p>\n","protected":false},"author":46738,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[],"class_list":["post-2425","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2425","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/46738"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=2425"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2425\/revisions"}],"predecessor-version":[{"id":41472,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2425\/revisions\/41472"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=2425"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=2425"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=2425"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=2425"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}