Hi Telerik,
I was wondering what the prescribed method is for tracking dynamically created panes. I have been working with RadDockLayout for some time and am wondering if it is possible to write an extension method that gives it the ability to keep track of the Panes on the page?
Let me shed some light on some of my issues:
There are a bunch of splitters and panes on the page. The user resizes them and I need to save the state of the controls through page refresh at this point. I am doing this by firing an ajax event on pane resized and then saving the states of all the panes.
The Utilities.FindControlRecurisve is just that, a recursive implementation of Page.FindControl. It is slow when there are large amounts of controls on the page, and I do not like calling it more than I absolutely have to, but I do not have a nice collection of monitored RadPanes already.
As such, I created a manager class for regenerating my controls.
If you would kindly look at the above "RegeneratedDockZones" function you will see that I have commented out my attempt at regenerating from my own list. While I seem to find the control just fine I noticed a lot of very weird problems occurring with my dashboard after attempting to load from "RegeneratedPanes". Yet, you can see in RegenerateSplitterChildren that I am working with the same pane which was already existing on the page / being recreated upon the splitter.
Do you see anything erroneous with this? Or anything I should be doing differently? I only have need to monitor RadPanes at this point in time, I was hoping this would be rather simple..
I was wondering what the prescribed method is for tracking dynamically created panes. I have been working with RadDockLayout for some time and am wondering if it is possible to write an extension method that gives it the ability to keep track of the Panes on the page?
Let me shed some light on some of my issues:
There are a bunch of splitters and panes on the page. The user resizes them and I need to save the state of the controls through page refresh at this point. I am doing this by firing an ajax event on pane resized and then saving the states of all the panes.
public
static
void
SavePanes()
{
foreach
(KeyValuePair<
string
, RadPaneSetting> paneState
in
GetStates<SerializableDictionary<
string
, RadPaneSetting>>().ToList())
{
CormantRadPane pane = Utilities.FindControlRecursive(HttpContext.Current.Handler
as
Page, paneState.Key)
as
CormantRadPane;
Save<RadPaneSetting>(pane);
}
}
The Utilities.FindControlRecurisve is just that, a recursive implementation of Page.FindControl. It is slow when there are large amounts of controls on the page, and I do not like calling it more than I absolutely have to, but I do not have a nice collection of monitored RadPanes already.
As such, I created a manager class for regenerating my controls.
public
class
RegenerationManager
{
private
static
readonly
ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private
static
readonly
RegenerationManager instance =
new
RegenerationManager();
private
RegenerationManager() { }
public
static
RegenerationManager Instance
{
get
{
return
instance; }
}
private
IList<CormantRadPane> _regeneratedPanes;
//Don't monitor RadDockZone or RadDock -- these are handled by RadDockLayout.
public
IList<CormantRadPane> RegeneratedPanes
{
get
{
if
(
object
.Equals(_regeneratedPanes,
null
))
{
_regeneratedPanes =
new
List<CormantRadPane>();
}
return
_regeneratedPanes;
}
}
/// <summary>
/// Recreates the page state recursively by creating a control and looking for its known children.
/// </summary>
/// <param name="splitter"> Splitter having children added to it. </param>
private
void
RegenerateSplitterChildren(RadSplitter splitter)
{
Logger.InfoFormat(
"Initializing splitter children for splitter {0}"
, splitter.ID);
foreach
(KeyValuePair<
string
, RadPaneSetting> paneState
in
RadControlManager.GetStates<SerializableDictionary<
string
, RadPaneSetting>>().Where(paneState => paneState.Value.ParentID == splitter.ID))
{
CormantRadPane pane =
new
CormantRadPane(paneState.Value);
RegeneratedPanes.Add(pane);
splitter.Controls.Add(pane);
RegeneratePaneChildren(pane);
InsertSplitBar(splitter);
}
}
/// <summary>
/// Recreates all the dynamically made DockZones.
/// </summary>
public
void
RegenerateDockZones()
{
Logger.Info(
"Regenerating dock zones."
);
foreach
(KeyValuePair<
string
, RadDockZoneSetting> dockZoneState
in
RadControlManager.GetStates<SerializableDictionary<
string
, RadDockZoneSetting>>())
{
try
{
RadDockZoneSetting dockZoneSetting = dockZoneState.Value
as
RadDockZoneSetting;
if
(dockZoneSetting.ID ==
"RadDockZone1"
)
continue
;
Logger.Info(String.Format(
"Loading state data for dock zone with setting ID: {0}"
, dockZoneSetting.ID));
CormantRadDockZone dockZone =
new
CormantRadDockZone(dockZoneSetting);
//CormantRadPane pane = RegeneratedPanes.First(regeneratedPane => regeneratedPane.ID == dockZoneSetting.ParentID);
CormantRadPane pane = Utilities.FindControlRecursive(HttpContext.Current.Handler
as
Page, dockZoneSetting.ParentID)
as
CormantRadPane;
pane.Controls.Add(dockZone);
}
catch
(Exception exception)
{
System.Diagnostics.Debug.Assert(
false
,
"Error!"
);
Logger.ErrorFormat(
"Error regenerating dock zones. Reason: {0}"
, exception.Message);
}
}
}
If you would kindly look at the above "RegeneratedDockZones" function you will see that I have commented out my attempt at regenerating from my own list. While I seem to find the control just fine I noticed a lot of very weird problems occurring with my dashboard after attempting to load from "RegeneratedPanes". Yet, you can see in RegenerateSplitterChildren that I am working with the same pane which was already existing on the page / being recreated upon the splitter.
Do you see anything erroneous with this? Or anything I should be doing differently? I only have need to monitor RadPanes at this point in time, I was hoping this would be rather simple..