Para aqueles que não conhecem o Kentico CMS, aconselho a darem uma olhadela à homepage deles, considero-o um bom CMS ( tendo em conta aquilo com que já trabalhei, Joomla e Mambo, que para mim são péssimos… )…
Têm várias versões de licenciamento do software, mas a meu ver são bastante irreais para o mercado português, então para a comunidade freelancer ainda pior, no entanto têm uma versão free, mas que têm uma condição.. da qual eu não gosto nada, para podermos usar a versão free temos de por o “branding” deles em todas as páginas que são geridas pelo CMS, não acredito que seja fácil vender isto a um cliente…
Mas no final, considero que é um excelente CMS, e na última versão que testei ( versão 4.0 ), está mesmo muito bom… já saiu a versão 4.1 ( no mês passado senão estou em erro )…
Mas voltando ao que me fez criar um post..
Ontem e hoje, estive à luta com um CMS:Repeater ( controlo do Kentico, basicamente fizeram um “extend” ao Repeater do .Net ) e com o CMS:TemplateDataPager…
Já tinha usado esta combinação 2 dias antes, e não tive problemas, só que tinha usado através de webpart’s clonadas ( clonei a webpart do Kentico CMS:Repeater ), desliguei o DataBindingByDefault e o EnablePagging do CMS:Repeater e problema resolvido, foi só afectar o TemplateDataPager com o DataSource do CMS:Repeater e problema resolvido…
Vendo o exemplo deles, é bastante fácil de o fazer:
Página:
<table style="border: solid 1px #CCCCCC; margin-left: auto; margin-right: auto;">
<tr>
<td style="border-bottom: solid 1px #CCCCCC; padding: 10px; text-align: center;">
<cc1:cmsrepeater id="CMSRepeater1" runat="server" path="/%" classnames="CMS.Product"
transformationname="CMS.Product.preview">
</cc1:cmsrepeater>
</td>
</tr>
<tr>
<td style="padding: 10px; background-color: #D9D9D9;">
<cc1:templatedatapager id="TemplateDataPager1" runat="server">
<NumberTemplate>
<a href="?Page=<%# Eval("PageNumber") %>"><%# Eval("PageNumber") %></a>
</NumberTemplate>
<SelectedNumberTemplate>
<b><%# Eval("PageNumber") %></b>
</SelectedNumberTemplate>
<SeparatorTemplate>
-
</SeparatorTemplate>
<FirstItemTemplate>
<a href="?Page=1">First</a> |
</FirstItemTemplate>
<LastItemTemplate>
| <a href="?Page=<%# pageCount %>">Last</a>
</LastItemTemplate>
<PreviousItemTemplate>
<a href="?Page=<%# previousPage %>">Previous</a> |
</PreviousItemTemplate>
<NextItemTemplate>
| <a href="?Page=<%# nextPage %>">Next</a>
</NextItemTemplate>
</cc1:templatedatapager>
</td>
</tr>
</table>
Code behind:
using CMS.GlobalHelper;
public partial class CMSControlsExamples_TemplatedDataPager : ControlsExamplesPage
{
public string pageCount = "1";
public string previousPage = "1";
public string nextPage = "";
///
/// OnInit override
///
///
protected override void OnInit(EventArgs e)
{
// Disable repeater pager and databindbydefault
CMSRepeater1.EnablePaging = false;
CMSRepeater1.DataBindByDefault = false;
base.OnInit(e);
}
protected void Page_Load(object sender, EventArgs e)
{
// Get repeater datasource
TemplateDataPager1.DataSource = CMSRepeater1.DataSource;
// Set page size
TemplateDataPager1.PageSize = 1;
// Set current page from query string
TemplateDataPager1.CurrentPage = ValidationHelper.GetInteger(Request.QueryString["Page"], 1);
// Get page number for last link
pageCount = ((int)(TemplateDataPager1.PageCount - 1)).ToString();
// Set default next page link
nextPage = pageCount;
// Set previous link
if ((TemplateDataPager1.CurrentPage - 1) >= 1)
{
previousPage = ((int)(TemplateDataPager1.CurrentPage - 1)).ToString();
}
// Set next link
if ((TemplateDataPager1.CurrentPage + 1) <= (TemplateDataPager1.PageCount - 1))
{
nextPage = ((int)(TemplateDataPager1.CurrentPage + 1)).ToString();
}
// Set paged datasource to the repeater and databind it
CMSRepeater1.DataSource = TemplateDataPager1.PagedData;
if (!DataHelper.DataSourceIsEmpty(CMSRepeater1.DataSource))
{
CMSRepeater1.DataBind();
}
}
}
Até aqui sem problemas, consegui-o usar sem acontecer nada, o problema surgiu foi quando tentei afectar o CMS:Repeater com um DataSource vindo de uma query, tentei de várias maneiras afectar o DataSource do CMS:TemplateDataPager, que o DataSource ficava sempre a vazio, apesar de a query estar a retornar 38000 resultados.
Estava a usar mais ou menos este código ( na realidade tenho as chamadas à base de dados encapsuladas com tratamento de excepções):
protected void Page_Load(object sender, EventArgs e)
{
GeneralConnection cn = new GeneralConnection();
DataSet ds = null;
object[,] parameters = new object[1, 3];
parameters[0, 0] = "@UserName";
parameters[0, 1] = "johns";
CMSRepeater1.DataSource = cn.ExecuteQuery("cms.user.selectbyname", parameters).Tables[0];
// Get repeater datasource
TemplateDataPager1.DataSource = CMSRepeater1.DataSource;
// Set page size
TemplateDataPager1.PageSize = 1;
// Set current page from query string
TemplateDataPager1.CurrentPage = ValidationHelper.GetInteger(Request.QueryString["Page"], 1);
// Get page number for last link
pageCount = ((int)(TemplateDataPager1.PageCount - 1)).ToString();
// Set default next page link
nextPage = pageCount;
// Set previous link
if ((TemplateDataPager1.CurrentPage - 1) >= 1)
{
previousPage = ((int)(TemplateDataPager1.CurrentPage - 1)).ToString();
}
// Set next link
if ((TemplateDataPager1.CurrentPage + 1) <= (TemplateDataPager1.PageCount - 1))
{
nextPage = ((int)(TemplateDataPager1.CurrentPage + 1)).ToString();
}
// Set paged datasource to the repeater and databind it
CMSRepeater1.DataSource = TemplateDataPager1.PagedData;
if (!DataHelper.DataSourceIsEmpty(CMSRepeater1.DataSource))
{
CMSRepeater1.DataBind();
}
}
Este código não faz absolutamente nada, ou melhor até faz, a query à base de dados é efectuada correctamente, retorna resultados, só que quando se afecta a DataSource do TemplateDataPager, esta ficava sempre a null…
E qual era o problema, é que pelos vistos quando afectava a DataSource do CMS:Repeater, a DataSource ficava com o tipo DataTable, até aqui tudo bem, se eu comentasse o CMS:TemplateDataPager, o CMS:Repeater era preenchido, o transform efectuado e tudo aparecia às mil maravilhas..
O que acontece é que o DataSource do CMS:TemplateDataPager tem de ser um DataView, em vez do DataTable..coisa simples não é?
Clonando a webpart deles, nunca afectamos directamente o DataSource do CMS:Repeater, este é afectado por eles, e o DataSource fica sempre com DataView, quer seja um CMS:Queryrepeater, quer seja um CMS:Repeater… por isso é que o erro não foi detectado nas webpart’s que tinha clonado anteriormente…
Após ter alterado o código para:
protected void Page_Load(object sender, EventArgs e)
{
GeneralConnection cn = new GeneralConnection();
DataSet ds = null;
object[,] parameters = new object[1, 3];
parameters[0, 0] = "@UserName";
parameters[0, 1] = "johns";
CMSRepeater1.DataSource = cn.ExecuteQuery("cms.user.selectbyname", parameters).Tables[0].DefaultView;
// Get repeater datasource
TemplateDataPager1.DataSource = CMSRepeater1.DataSource;
// Set page size
TemplateDataPager1.PageSize = 1;
// Set current page from query string
TemplateDataPager1.CurrentPage = ValidationHelper.GetInteger(Request.QueryString["Page"], 1);
// Get page number for last link
pageCount = ((int)(TemplateDataPager1.PageCount - 1)).ToString();
// Set default next page link
nextPage = pageCount;
// Set previous link
if ((TemplateDataPager1.CurrentPage - 1) >= 1)
{
previousPage = ((int)(TemplateDataPager1.CurrentPage - 1)).ToString();
}
// Set next link
if ((TemplateDataPager1.CurrentPage + 1) <= (TemplateDataPager1.PageCount - 1))
{
nextPage = ((int)(TemplateDataPager1.CurrentPage + 1)).ToString();
}
// Set paged datasource to the repeater and databind it
CMSRepeater1.DataSource = TemplateDataPager1.PagedData;
if (!DataHelper.DataSourceIsEmpty(CMSRepeater1.DataSource))
{
CMSRepeater1.DataBind();
}
}
Ficou tudo a funcionar às mil maravilhas..
Nem imaginam as voltas que dei para encontrar esta solução, estava difícil mas consegui..
Um bem haja a todos e bom código..