Visão Geral das Edições
A distribuição gratuita do Kendo UI possui limitações significativas: não inclui o módulo DataViz para visualizações gráficas e, crucialmente, não oferece suporte a helpers do lado do servidor. Isso significa que desenvolvedores .NET não contam com os wrappers MVC que simplificam a geração de JavaScript através de código C#.
A versão paga, especificamente o pacote destinado ao ecossistema ASP.NET MVC, resolve essas restrições. Os helpers utilizam expressões lambda para configuração, proporcionando uma experiência fluente e fortemente tipada. A decisão entre as edições depende da composição da equipe: profissionais especializados em frontend podem se adequar à versão gratuita, enquanto equipes full-stack .NET se beneficiam substancialmente dos recursos pagos.
Resolvendo Conflitos Visuais com Bootstrap
A integração entre Kendo UI e Bootstrap 3 apresenta incompatibilidades relacionadas à propriedade box-sizing. A solução envolve redefinir o comportamento de dimensionamento para componentes específicos do Kendo:
/* Correção de compatibilidade Kendo UI + Bootstrap 3 */
.componente-kendo,
.componente-kendo *,
.container-animacao * {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.barra-titulo-modal.cabecalho {
-moz-box-sizing: content-box !important;
-webkit-box-sizing: content-box !important;
box-sizing: content-box !important;
}
.titulo-modal {
font-size: 12px;
}
Importante: estas regras devem ser carregadas após o CSS do Bootstrap para garantir precedência. Em alguns cenários, ajustar para border-box pode ser necessário conforme a estrutura específica do projeto.
Configuração de Data Binding no Grid
Problemas comuns de vinculação de dados geralmente originam-se de dois fatores:
Ordem de carergamento de scripts: O jQuery deve estar disponível antes da inicialização dos componentes Kendo. Templates padrão do MVC4 posicionam o jQuery no final da página, o que conflita com a renderização dos helpers. A solução é mover a referência do jQuery para a seção <head>.
Script auxiliar obrigatório: O arquivo kendo.aspnetmvc.min.js habilita comunicação via POST e model binding correto no servidor. Sem ele, o grid utiliza requisições GET que não integram adequadamente com o pipeline MVC.
Para operações remotas, a action deve retornar JsonResult (ou ActionResult que encapsule um) e aceitar o parâmetro decorado com [DataSourceRequest]:
public ActionResult ObterDadosGrid([DataSourceRequest] DataSourceRequest requisicao)
{
var consulta = _contexto.Entidades.AsQueryable();
var resultado = consulta.ToDataSourceResult(requisicao);
return Json(resultado, JsonRequestBehavior.AllowGet);
}
A extansão ToDataSourceResult processa paginação, ordenação e filtragem automaticamente quando aplicada sobre IQueryable. Para fontes de dados não queryáveis, consulte a documentação de custom binding.
Implementação de Colunas de Chave Estrangeira
A configuração de colunas que exibam dropdowns em modo de edição exige múltiplas camadas de configuração:
Preparação de dados no controller:
private void CarregarCategorias()
{
var categorias = _contexto.Categorias
.Select(c => new CategoriaViewModel
{
Codigo = c.Id,
Descricao = c.Nome
})
.OrderBy(c => c.Descricao)
.ToList();
ViewData["listaCategorias"] = categorias;
ViewData["categoriaPadrao"] = categorias.FirstOrDefault();
}
public ActionResult Index()
{
CarregarCategorias();
return View();
}
Configuração do grid:
colunas.ForeignKey(p => p.CategoriaCodigo,
(IEnumerable<CategoriaViewModel>)ViewData["listaCategorias"],
"Codigo", "Descricao")
.Titulo("Categoria");
Modelo de dados com valores padrão:
modelo.Id(p => p.Identificador);
modelo.Campo(p => p.Identificador).Editavel(false);
modelo.Campo(p => p.CategoriaCodigo)
.ValorPadrao(((CategoriaViewModel)ViewData["categoriaPadrao"]).Codigo);
A definição do valor padrão é obrigatória — sem ela, dropdowns com única opção não transmitem dados ao servidor.
Template de editor personalizado (~/Views/Shared/EditorTemplates/CategoriaDropdown.cshtml):
@using Kendo.Mvc.UI
@(Html.Kendo().DropDownListFor(m => m)
.ValorCampo("Codigo")
.TextoCampo("Descricao")
.VincularDados((System.Collections.IEnumerable)ViewData["listaCategorias"])
)
Decorador no modelo:
public class ProdutoGridModel
{
public Guid Identificador { get; set; }
[UIHint("CategoriaDropdown")]
public Guid? CategoriaCodigo { get; set; }
[UIHint("SeletorNumerico")]
public int QuantidadeEstoque { get; set; }
[UIHint("Data")]
public DateTime? DataCadastro { get; set; }
}
Modal com Centralização Dinâmica
Para exibir uma janela modal apenas sob demanda e centralizada, a abordagem via JavaScript direto é necessária:
<div id="containerModal"></div>
<script>
$(function() {
$("#btnVisualizar").click(function() {
if (!registroSelecionado) {
alert('Selecione um registro primeiro');
return;
}
$("#containerModal").kendoWindow({
modal: true,
iframe: true,
arrastavel: true,
fixo: false,
titulo: "@ViewBag.TituloProduto",
redimensionavel: true,
conteudo: "@Url.Action("Grafico", "Relatorios")?id=" + registroSelecionado,
largura: 720,
altura: 480,
acoes: ["Atualizar", "Maximizar", "Fechar"]
});
var modal = $("#containerModal").data("kendoWindow");
modal.abrir();
modal.centralizar();
});
});
</script>
Escala Automática em Gráficos de Linha
Gráficos de série temporal frequentemente apresentam aglomeração de pontos. Para intervalos dinâmicos baseados na densidade de dados:
.EixoCategorias(eixo => eixo
.Justificar()
.Data()
.PassosBaseAutomaticos(passos => {
passos.Dias(1);
passos.Semanas(2);
passos.Meses(3);
})
.PassoUnidadeBase(0)
.Categorias(modelo => modelo.DataPublicacao.Value)
)
O valor 0 para PassoUnidadeBase ativa o cálculo automático de intervalos. Qualquer valor positivo impõe intervalos fixos, frequentemente resultando em sobreposição visual.