Integração do Kendo UI com ASP.NET MVC: Guia Prático de Soluções

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.

Tags: kendo-ui asp.net-mvc bootstrap grid-component data-visualization

Publicado em 10-2 18:57