Czy poniższy kod zawierający wywołanie metody LoadControl wydaje się wam poprawny? Jeśli tak to zapraszam do dalszej lektury.
protected void Page_Load(object sender, EventArgs e) { ... Control control = LoadControl("~/MySimpleUserControl.ascx"); PlaceHolder1.Controls.Add(control); ((MySimpleUserControl)control).BackColor = Color.Yellow; ... }
Niestety ale kod ten będzie działał poprawnie tylko do momentu kiedy dla kontrolki zostanie włączony mechanizm Output Cache, na przykład w następujący sposób:
<%@ OutputCache Duration="60" VaryByParam="None" %>
W takim przypadku, przy następnym ładowaniu strony, na której umieszczono kontrolkę, pojawi się wyjątek InvalidCastException z komunikatem: "Unable to cast object of type ‘System.Web.UI.PartialCachingControl’ to type ‘MySimpleUserControl’.". Dzieje się tak ponieważ metoda LoadControl, w przypadku kiedy włączone jest cache'owanie dla kontrolki, zwraca obiekt klasy PartialCachingControl, a nie klasy MySimpleUserControl jak mogłoby się wydawać. W takie sytuacji do kontrolki możemy się dostać przez właściwość PartialCachingControl.CachedControl. Poprawny kod powinien, więc wyglądać tak:
protected void Page_Load(object sender, EventArgs e) { ... Control control = LoadControl("~/MySimpleUserControl.ascx"); PlaceHolder1.Controls.Add(control); MySimpleUserControl c = control as MySimpleUserControl; if(c == null) { PartialCachingControl pc = control as PartialCachingControl; c = pc.CachedControl as MySimpleUserControl; } if(c != null) c.BackColor = Color.Yellow; ... }
Dodatkowe sprawdzenie if(c != null) jest potrzebne ponieważ właściwość PartialCachingControl.CachedControl zwróci null jeśli kontrolka znajduje się już w cache'u. Innymi słowy wartość różna od null zostanie zwrócona tylko wtedy kiedy kontrolka nie została jeszcze umieszczona w cache albo zawartość cache przestała być ważna.
Należy również pamiętać aby odwołanie do PartialCachingControl.CachedControl było zawsze poprzedzone umieszczeniem kontrolki na stronie np.: PlaceHolder1.Controls.Add(control);. W przeciwnym wypadku właściwość PartialCachingControl.CachedControl zawsze zwróci null.
W przypadku kiedy korzystamy z cache'owania i mamy na stronie statycznie osadzone kontrolki również należy zachować ostrożność. Jeśli kontrolka zostanie pobrana z cache to nie zostanie zainicjowana i nie możemy w związku z tym odwołać się do niej w kodzie naszej strony. Oczywiście jest to jak najbardziej prawidołe zachowanie - na tym polega idea mechanizmu Output Cache.
0 comments:
Post a Comment