Partilhar via


Introdução ao MonoTouch.Dialog para Xamarin.iOS

MonoTouch.Dialog, conhecido como MT. D, para abreviar, é um kit de ferramentas de desenvolvimento rápido de interface do usuário que permite que os desenvolvedores criem telas de aplicativos e navegação usando informações, em vez do tédio de criar controladores de exibição, tabelas etc. Dessa forma, ele fornece uma simplificação significativa do desenvolvimento da interface do usuário e da redução de código. Por exemplo, considere a seguinte captura de tela:

Por exemplo, considere esta captura de tela

O código a seguir foi usado para definir toda esta tela:

public enum Category
{
    Travel,
    Lodging,
    Books
}
        
public class Expense
{
    [Section("Expense Entry")]

    [Entry("Enter expense name")]
    public string Name;
    [Section("Expense Details")]
  
    [Caption("Description")]
    [Entry]
    public string Details;
        
    [Checkbox]
    public bool IsApproved = true;
    [Caption("Category")]
    public Category ExpenseCategory;
}

Ao trabalhar com tabelas no iOS, geralmente há uma tonelada de código repetido. Por exemplo, sempre que uma tabela é necessária, uma fonte de dados é necessária para preencher essa tabela. Em um aplicativo que tem duas telas baseadas em tabela conectadas por meio de um controlador de navegação, cada tela compartilha muito do mesmo código.

MT. D simplifica isso encapsulando todo esse código em uma API genérica para criação de tabela. Em seguida, ele fornece uma abstração sobre essa API que permite uma sintaxe declarativa de associação de objeto que facilita ainda mais. Dessa forma, há duas APIs disponíveis em MT. D:

  • API de Elementos de baixo nível – a API Elements baseia-se na criação de uma árvore hierárquica de elementos que representam telas e seus componentes. A API de Elementos oferece aos desenvolvedores a maior flexibilidade e controle na criação de interfaces do usuário. Além disso, a API de Elementos tem suporte avançado para definição declarativa por meio de JSON, o que permite uma declaração incrivelmente rápida, bem como a geração dinâmica de interface do usuário de um servidor.
  • API de Reflexão de Alto Nível – também conhecida como API de Associação , na qual as classes são anotadas com dicas de interface do usuário e, em seguida, MT. D cria automaticamente telas com base nos objetos e fornece uma associação entre o que é exibido (e, opcionalmente, editado) na tela e o backup de objeto subjacente. O exemplo acima ilustrava o uso da API de Reflexão. Essa API não fornece o controle refinado que a API de elementos faz, mas reduz ainda mais a complexidade criando automaticamente a hierarquia de elementos com base em atributos de classe.

MT. D vem embalado com um grande conjunto de elementos de interface do usuário internos para criação de tela, mas também reconhece a necessidade de elementos personalizados e layouts de tela avançados. Dessa forma, a extensibilidade é um recurso de primeira classe inserido na API. Os desenvolvedores podem estender os elementos existentes ou criar novos e, em seguida, integrar-se perfeitamente.

Além disso, MT. D tem uma série de recursos comuns de UX do iOS internos, como suporte a "pull-to-refresh", carregamento de imagem assíncrona e suporte à pesquisa.

Este artigo dará uma visão abrangente sobre como trabalhar com MT. D, incluindo:

  • MT. Componentes D – isso se concentrará na compreensão das classes que compõem o MT. D para habilitar a aceleração rapidamente.
  • Referência de elementos – uma lista abrangente dos elementos internos do MT.D.
  • Uso Avançado – abrange recursos avançados, como pull-to-refresh, pesquisa, carregamento de imagens em segundo plano, uso do LINQ para criar hierarquias de elementos e criação de elementos personalizados, células e controladores para uso com MT.D.

Configurando MT. D

MT. D é distribuído com Xamarin.iOS. Para usá-lo, clique com o botão direito do mouse no nó Referências de um projeto Xamarin.iOS no Visual Studio 2017 ou Visual Studio para Mac e adicione uma referência ao assembly MonoTouch.Dialog-1. Em seguida, adicione using MonoTouch.Dialog instruções ao código-fonte conforme necessário.

Noções básicas sobre as partes de MT. D

Mesmo ao usar a API de Reflexão, MT. D cria uma hierarquia de elementos sob o capô, assim como se tivesse sido criada por meio da API de Elementos diretamente. Além disso, o suporte JSON mencionado na seção anterior também cria Elementos. Por esse motivo, é importante ter uma compreensão básica das partes constituintes da MT.D.

MT. D cria telas usando as quatro partes a seguir:

  • DialogViewController
  • Rootelement
  • Seção
  • Element

DialogViewController

Um DialogViewController, ou DVC para abreviar, herda de UITableViewController e, portanto, representa uma tela com uma tabela. Os DVCs podem ser enviados por push para um controlador de navegação, assim como um UITableViewController regular.

Rootelement

Um RootElement é o contêiner de nível superior para os itens que entram em um DVC. Ele contém Seções, que podem conter Elementos. RootElements não são renderizados; em vez disso, eles são simplesmente contêineres para o que realmente é renderizado. Um RootElement é atribuído a um DVC e, em seguida, o DVC renderiza seus filhos.

Seção

Uma seção é um grupo de células em uma tabela. Assim como acontece com uma seção de tabela normal, ele pode ter opcionalmente um cabeçalho e rodapé que podem ser texto ou até mesmo modos de exibição personalizados, como na captura de tela a seguir:

Assim como acontece com uma seção de tabela normal, ele pode ter opcionalmente um cabeçalho e rodapé que podem ser texto ou até mesmo modos de exibição personalizados, como nesta captura de tela

Elemento

Um Elemento representa uma célula real na tabela. MT. D vem embalado com uma ampla variedade de Elementos que representam diferentes tipos de dados ou entradas diferentes. Por exemplo, as capturas de tela a seguir ilustram alguns dos elementos disponíveis:

Por exemplo, essas capturas de tela ilustram alguns dos elementos disponíveis

Mais informações sobre Seções e RootElements

Agora vamos discutir RootElements e Seções com mais detalhes.

RootElements

Pelo menos um RootElement é necessário para iniciar o processo MonoTouch.Dialog.

Se um RootElement for inicializado com um valor de seção/elemento, esse valor será usado para localizar um Elemento filho que fornecerá um resumo da configuração, que é renderizada no lado direito da exibição. Por exemplo, a captura de tela abaixo mostra uma tabela à esquerda com uma célula contendo o título da tela de detalhes à direita, "Sobremesa", juntamente com o valor do deserto selecionado.

Esta captura de tela mostra uma tabela à esquerda com uma célula contendo o título da tela de detalhes à direita, Sobremesa, juntamente com o valor do deserto selecionadoEsta captura de tela abaixo mostra uma tabela à esquerda com uma célula contendo o título da tela de detalhes à direita, Sobremesa, juntamente com o valor do deserto selecionado

Os elementos raiz também podem ser usados dentro de Seções para disparar o carregamento de uma nova página de configuração aninhada, conforme mostrado acima. Quando usado nesse modo, o legenda fornecido é usado enquanto renderizado dentro de uma seção e também é usado como o Título para a subpágina. Por exemplo:

var root = new RootElement ("Meals") {
    new Section ("Dinner") {
        new RootElement ("Dessert", new RadioGroup ("dessert", 2)) {
            new Section () {
                new RadioElement ("Ice Cream", "dessert"),
                new RadioElement ("Milkshake", "dessert"),
                new RadioElement ("Chocolate Cake", "dessert")
            }
        }
    }
};

No exemplo acima, quando o usuário toca em "Sobremesa", o MonoTouch.Dialog criará uma nova página e navegará até ela com a raiz sendo "Sobremesa" e tendo um grupo de rádio com três valores.

Neste exemplo específico, o grupo de rádio selecionará "Bolo de Chocolate" na seção "Sobremesa" porque passamos o valor "2" para o RadioGroup. Isso significa escolher o 3º item na lista (índice zero).

Chamar o método Add ou usar a sintaxe do inicializador C# 4 adiciona seções. Os métodos Insert são fornecidos para inserir seções com uma animação.

Se você criar o RootElement com uma instância de Grupo (em vez de um RadioGroup), o valor resumido do RootElement quando exibido em uma Seção será a contagem cumulativa de todos os BooleanElements e CheckboxElements que têm a mesma chave que o valor Group.Key.

Seções

As seções são usadas para agrupar elementos na tela e são os únicos filhos diretos válidos do RootElement. As seções podem conter qualquer um dos elementos padrão, incluindo novos RootElements.

RootElements inseridos em uma seção são usados para navegar para um novo nível mais profundo.

As seções podem ter cabeçalhos e rodapés como cadeias de caracteres ou como UIViews. Normalmente, você usará apenas as cadeias de caracteres, mas para criar interfaces do usuário personalizadas, você pode usar qualquer UIView como cabeçalho ou rodapé. Você pode usar uma cadeia de caracteres para criá-las desta forma:

var section = new Section ("Header", "Footer");

Para usar exibições, basta passar as exibições para o construtor:

var header = new UIImageView (Image.FromFile ("sample.png"));
var section = new Section (header);

Recebendo notificação

Tratamento de NSAction

MT. D exibe um NSAction como um delegado para lidar com retornos de chamada. Por exemplo, digamos que você queira manipular um evento de toque para uma célula de tabela criada pelo MT.D. Ao criar um elemento com MT. D, basta fornecer uma função de retorno de chamada, conforme mostrado abaixo:

new Section () {
    new StringElement ("Demo Callback", delegate { Console.WriteLine ("Handled"); })
}

Recuperando o valor do elemento

Combinado com a Element.Value propriedade , o retorno de chamada pode recuperar o valor definido em outros elementos. Por exemplo, considere o seguinte código:

var element = new EntryElement (task.Name, "Enter task description", task.Description);
                
var taskElement = new RootElement (task.Name) {
    new Section () { element },
    new Section () { new DateElement ("Due Date", task.DueDate) },
    new Section ("Demo Retrieving Element Value") {
        new StringElement ("Output Task Description", delegate { Console.WriteLine (element.Value); })
    }
};

Esse código cria uma interface do usuário, conforme mostrado abaixo. Para obter um passo a passo completo deste exemplo, consulte o tutorial passo a passo da API de Elementos .

Combinado com a propriedade Element.Value, o retorno de chamada pode recuperar o valor definido em outros elementos

Quando o usuário pressiona a célula da tabela inferior, o código na função anônima é executado, gravando o valor da element instância no painel Saída do Aplicativo em Visual Studio para Mac.

Elementos Built-In

MT. D vem com uma série de itens de célula de tabela internos conhecidos como Elementos. Esses elementos são usados para exibir uma variedade de tipos diferentes em células de tabela, como cadeias de caracteres, floats, datas e até imagens, para citar apenas alguns. Cada elemento cuida da exibição adequada do tipo de dados. Por exemplo, um elemento booliano exibirá uma opção para alternar seu valor. Da mesma forma, um elemento float exibirá um controle deslizante para alterar o valor float.

Há elementos ainda mais complexos para dar suporte a tipos de dados mais avançados, como imagens e html. Por exemplo, um elemento html, que abrirá um UIWebView para carregar uma página da Web quando selecionado, exibe um legenda na célula da tabela.

Trabalhando com valores de elemento

Elementos usados para capturar a entrada do usuário expõem uma propriedade pública Value que contém o valor atual do elemento a qualquer momento. Ele é atualizado automaticamente à medida que o usuário usa o aplicativo.

Esse é o comportamento de todos os Elementos que fazem parte do MonoTouch.Dialog, mas não é necessário para elementos criados pelo usuário.

Elemento String

Um StringElement mostra um legenda no lado esquerdo de uma célula de tabela e o valor da cadeia de caracteres no lado direito da célula.

Um StringElement mostra um legenda no lado esquerdo de uma célula de tabela e o valor da cadeia de caracteres no lado direito da célula

Para usar um StringElement como um botão, forneça um delegado.

new StringElement ("Click me", () => { 
    new UIAlertView("Tapped", "String Element Tapped", null, "ok", null).Show();
});

Para usar um StringElement como um botão, forneça um delegado

Elemento String Estilizado

Um StyledStringElement permite que cadeias de caracteres sejam apresentadas usando estilos de célula de tabela internos ou com formatação personalizada.

Um StyledStringElement permite que cadeias de caracteres sejam apresentadas usando estilos de célula de tabela internos ou com formatação personalizada

A StyledStringElement classe deriva de StringElement, mas permite que os desenvolvedores personalizem um punhado de propriedades como Fonte, cor do texto, cor da célula de plano de fundo, modo de quebra de linha, número de linhas a serem exibidas e se um acessório deve ser exibido.

Elemento Multiline

Elemento Multiline

Elemento entry

O EntryElement, como o nome indica, é usado para obter a entrada do usuário. Ele dá suporte a cadeias de caracteres regulares ou senhas, em que os caracteres estão ocultos.

O EntryElement é usado para obter a entrada do usuário

Ele é inicializado com três valores:

  • O legenda para a entrada que será mostrada ao usuário.
  • Texto do espaço reservado (este é o texto esmaecido que fornece uma dica para o usuário).
  • O valor do texto.

O espaço reservado e o valor podem ser nulos. No entanto, o legenda é necessário.

A qualquer momento, acessar sua propriedade Value pode recuperar o valor do EntryElement.

Além disso, a KeyboardType propriedade pode ser definida no momento da criação para o estilo de tipo de teclado desejado para a entrada de dados. Isso pode ser usado para configurar o teclado usando os valores de UIKeyboardType , conforme listado abaixo:

  • Numérico
  • Telefone
  • Url
  • Email

Elemento booliano

Elemento booliano

Elemento Checkbox

Elemento Checkbox

Elemento Radio

Um RadioElement requer que um RadioGroup seja especificado no RootElement.

mtRoot = new RootElement ("Demos", new RadioGroup("MyGroup", 0));

Um RadioElement requer que um RadioGroup seja especificado no RootElement

RootElements também são usados para coordenar elementos de rádio. Os RadioElement membros podem abranger várias seções (por exemplo, para implementar algo semelhante ao seletor de tom de anel e separar os tons de anel personalizados dos toques do sistema). A exibição de resumo mostrará o elemento de rádio que está selecionado no momento. Para usar isso, crie o RootElement com o construtor de grupo, da seguinte maneira:

var root = new RootElement ("Meals", new RadioGroup ("myGroup", 0));

O nome do grupo em RadioGroup é usado para mostrar o valor selecionado na página que contém (se houver) e o valor, que é zero nesse caso, é o índice do primeiro item selecionado.

Elemento Badge

Elemento Badge

Elemento Float

Elemento Float

Elemento Activity

Elemento Activity

Elemento Date

Elemento Date

Quando a célula correspondente ao DateElement é selecionada, um seletor de data é apresentado conforme mostrado abaixo:

Quando a célula correspondente ao DateElement é selecionada, um seletor de data é apresentado conforme mostrado

Elemento Time

Elemento Time

Quando a célula correspondente ao TimeElement é selecionada, um seletor de horário é apresentado conforme mostrado abaixo:

Quando a célula correspondente ao TimeElement é selecionada, um seletor de tempo é apresentado conforme mostrado

Elemento DateTime

Elemento DateTime

Quando a célula correspondente ao DateTimeElement é selecionada, um seletor de datetime é apresentado conforme mostrado abaixo:

Quando a célula correspondente ao DateTimeElement é selecionada, um seletor de datetime é apresentado conforme mostrado

Elemento HTML

Elemento HTML

O HTMLElement exibe o valor de sua Caption propriedade na célula da tabela. Selecionado, o Url atribuído ao elemento é carregado em um UIWebView controle, conforme mostrado abaixo:

Selecionado, a URL atribuída ao elemento é carregada em um controle UIWebView, conforme mostrado abaixo

Elemento Message

Elemento Message

Elemento Load More

Use esse elemento para permitir que os usuários carreguem mais itens em sua lista. Você pode personalizar as legendas normais e de carregamento, bem como a fonte e a cor do texto. O UIActivity indicador começa a animar e o legenda de carregamento é exibido quando um usuário toca na célula e, em seguida, o NSAction passado para o construtor é executado. Depois que o NSAction código no for concluído, o UIActivity indicador deixará de animar e a legenda normal será exibida novamente.

Elemento UIView

Além disso, qualquer personalizado UIView pode ser exibido usando o UIViewElement.

Elemento Owner-Drawn

Esse elemento deve ser subclasse, pois é uma classe abstrata. Você deve substituir o Height(RectangleF bounds) método no qual você deve retornar a altura do elemento, bem como Draw(RectangleF bounds, CGContext context, UIView view) no qual você deve fazer todo o desenho personalizado dentro dos limites fornecidos, usando os parâmetros de contexto e exibição. Esse elemento faz o trabalho pesado de subclasse de um UIViewe colocá-lo na célula a ser retornada, deixando você precisando apenas implementar duas substituições simples. Você pode ver uma implementação de exemplo melhor no aplicativo de exemplo no DemoOwnerDrawnElement.cs arquivo.

Aqui está um exemplo muito simples de implementação da classe:

public class SampleOwnerDrawnElement : OwnerDrawnElement
{
    public SampleOwnerDrawnElement (string text) : base(UITableViewCellStyle.Default, "sampleOwnerDrawnElement")
    {
        this.Text = text;
    }

    public string Text { get; set; }

    public override void Draw (RectangleF bounds, CGContext context, UIView view)
    {
        UIColor.White.SetFill();
        context.FillRect(bounds);

        UIColor.Black.SetColor();   
        view.DrawString(this.Text, new RectangleF(10, 15, bounds.Width - 20, bounds.Height - 30), UIFont.BoldSystemFontOfSize(14.0f), UILineBreakMode.TailTruncation);
    }

    public override float Height (RectangleF bounds)
    {
        return 44.0f;
    }
}

Elemento JSON

O JsonElement é uma subclasse de RootElement que estende um RootElement para ser capaz de carregar o conteúdo do filho aninhado de uma URL local ou remota.

O JsonElement é um RootElement que pode ser instanciado em duas formas. Uma versão cria um RootElement que carregará o conteúdo sob demanda. Eles são criados usando os JsonElement construtores que usam um argumento extra no final, a URL para carregar o conteúdo de:

var je = new JsonElement ("Dynamic Data", "https://tirania.org/tmp/demo.json");

O outro formulário cria os dados de um arquivo local ou de um existente System.Json.JsonObject que você já analisou:

var je = JsonElement.FromFile ("json.sample");
using (var reader = File.OpenRead ("json.sample"))
    return JsonElement.FromJson (JsonObject.Load (reader) as JsonObject, arg);

Para obter mais informações sobre como usar JSON com MT. D, consulte o tutorial passo a passo do elemento JSON .

Outros recursos

Suporte de pull-to-refresh

Pull-to-Refresh é um efeito visual originalmente encontrado no aplicativo Tweetie2, que se tornou um efeito popular entre muitos aplicativos.

Para adicionar suporte automático de pull-to-refresh às caixas de diálogo, você só precisa fazer duas coisas: conectar um manipulador de eventos para ser notificado quando o usuário efetuar pull dos dados e notificar o DialogViewController quando os dados foram carregados para voltar ao estado padrão.

Conectar uma notificação é simples; basta conectar-se ao RefreshRequested evento no DialogViewController, desta forma:

dvc.RefreshRequested += OnUserRequestedRefresh;

Em seguida, em seu método OnUserRequestedRefresh, você enfileiraria alguns dados carregando, solicitaria alguns dados da rede ou giraria um thread para calcular os dados. Depois que os dados forem carregados, você deverá notificar o DialogViewController em que os novos dados estão e, para restaurar o modo de exibição para seu estado padrão, faça isso chamando ReloadComplete:

dvc.ReloadComplete ();

Suporte à pesquisa

Para dar suporte à pesquisa, defina a EnableSearch propriedade em seu DialogViewController. Você também pode definir a SearchPlaceholder propriedade a ser usada como o texto da marca d'água na barra de pesquisa.

A pesquisa alterará o conteúdo do modo de exibição conforme o usuário digita. Ele pesquisa os campos visíveis e os mostra ao usuário. O DialogViewController expõe três métodos para iniciar, encerrar ou disparar programaticamente uma nova operação de filtro nos resultados. Estes métodos estão listados abaixo:

  • StartSearch
  • FinishSearch
  • PerformFilter

O sistema é extensível, portanto, você pode alterar esse comportamento se desejar.

Carregamento de imagens de plano de fundo

MonoTouch.Dialog incorpora o carregador de imagens do aplicativo TweetStation . Esse carregador de imagem pode ser usado para carregar imagens em segundo plano, dá suporte ao cache e pode notificar seu código quando a imagem tiver sido carregada.

Ele também limitará o número de conexões de rede de saída.

O carregador de imagem é implementado na classe , tudo o ImageLoader que você precisa fazer é chamar o DefaultRequestImage método , você precisará fornecer o Uri para a imagem que deseja carregar, bem como uma instância da IImageUpdated interface que será invocada quando a imagem tiver sido carregada.

Por exemplo, o código a seguir carrega uma imagem de uma URL em um BadgeElement:

string uriString = "http://some-server.com/some image url";

var rootElement = new RootElement("Image Loader") {
    new Section() {
        new BadgeElement( ImageLoader.DefaultRequestImage( new Uri(uriString), this), "Xamarin")
    }
};

A classe ImageLoader expõe um método Purge que você pode chamar quando deseja liberar todas as imagens armazenadas em cache na memória no momento. O código atual tem um cache para 50 imagens. Se você quiser usar um tamanho de cache diferente (por exemplo, se você espera que as imagens sejam muito grandes que 50 imagens seriam demais), basta criar instâncias do ImageLoader e passar o número de imagens que deseja manter no cache.

Usando LINQ para criar hierarquia de elementos

Por meio do uso inteligente da sintaxe de inicialização do LINQ e do C#, o LINQ pode ser usado para criar uma hierarquia de elementos. Por exemplo, o código a seguir cria uma tela de algumas matrizes de cadeia de caracteres e manipula a seleção de célula por meio de uma função anônima que é passada para cada StringElement:

var rootElement = new RootElement ("LINQ root element") {
    from x in new string [] { "one", "two", "three" }
    select new Section (x) {
        from y in "Hello:World".Split (':')
        select (Element) new StringElement (y, delegate { Debug.WriteLine("cell tapped"); })
    }
};

Isso pode ser facilmente combinado com um armazenamento de dados XML ou dados de um banco de dados para criar aplicativos complexos quase inteiramente a partir de dados.

Estendendo MT. D

Criando elementos personalizados

Você pode criar seu próprio elemento herdando de um Elemento existente ou derivando da classe raiz Element.

Para criar seu próprio Elemento, você desejará substituir os seguintes métodos:

// To release any heavy resources that you might have
void Dispose (bool disposing);

// To retrieve the UITableViewCell for your element
// you would need to prepare the cell to be reused, in the
// same way that UITableView expects reusable cells to work
UITableViewCell GetCell (UITableView tv);

// To retrieve a "summary" that can be used with
// a root element to render a summary one level up.  
string Summary ();

// To detect when the user has tapped on the cell
void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath path);

// If you support search, to probe if the cell matches the user input
bool Matches (string text);

Se o elemento puder ter um tamanho variável, você precisará implementar a IElementSizing interface , que contém um método:

// Returns the height for the cell at indexPath.Section, indexPath.Row
float GetHeight (UITableView tableView, NSIndexPath indexPath);

Se você estiver planejando implementar seu GetCell método chamando base.GetCell(tv) e personalizando a célula retornada, também precisará substituir a CellKey propriedade para retornar uma chave que será exclusiva para seu Elemento, desta forma:

static NSString MyKey = new NSString ("MyKey");
protected override NSString CellKey {
    get {
        return MyKey;
    }
}

Isso funciona para a maioria dos elementos, mas não para o StringElement e StyledStringElement , pois eles usam seu próprio conjunto de chaves para vários cenários de renderização. Você teria que replicar o código nessas classes.

DialogViewControllers (DVCs)

A Reflexão e a API de Elementos usam o mesmo DialogViewController. Às vezes, você desejará personalizar a aparência do modo de exibição ou talvez queira usar alguns recursos do UITableViewController que vão além da criação básica de interfaces do usuário.

O DialogViewController é apenas uma subclasse do UITableViewController e você pode personalizá-lo da mesma maneira que personalizaria um UITableViewController.

Por exemplo, se você quisesse alterar o estilo de lista para Grouped ou Plain, poderia definir esse valor alterando a propriedade ao criar o controlador, desta forma:

var myController = new DialogViewController (root, true) {
    Style = UITableViewStyle.Grouped;
}

Para personalizações mais avançadas do , como definir DialogViewControllersua tela de fundo, você a subclasse e substituiria os métodos adequados, conforme mostrado no exemplo abaixo:

class SpiffyDialogViewController : DialogViewController {
    UIImage image;

    public SpiffyDialogViewController (RootElement root, bool pushing, UIImage image) 
        : base (root, pushing) 
    {
        this.image = image;
    }

    public override LoadView ()
    {
        base.LoadView ();
        var color = UIColor.FromPatternImage(image);
        TableView.BackgroundColor = UIColor.Clear;
        ParentViewController.View.BackgroundColor = color;
    }
}

Outro ponto de personalização são os seguintes métodos virtuais no DialogViewController:

public override Source CreateSizingSource (bool unevenRows)

Esse método deve retornar uma subclasse de DialogViewController.Source para casos em que suas células são dimensionadas uniformemente ou uma subclasse de DialogViewController.SizingSource se as células estiverem desiguais.

Você pode usar essa substituição para capturar qualquer um dos UITableViewSource métodos. Por exemplo, o TweetStation usa isso para acompanhar quando o usuário rolar para a parte superior e atualizar de acordo com o número de tweets não lidos.

Validação

Os elementos não fornecem validação por conta própria, pois os modelos adequados para páginas da Web e aplicativos da área de trabalho não são mapeados diretamente para o modelo de interação do iPhone.

Se você quiser fazer a validação de dados, faça isso quando o usuário disparar uma ação com os dados inseridos. Por exemplo, um botão Concluído ou Próximo na barra de ferramentas superior ou alguns StringElement usados como um botão para ir para o próximo estágio.

É aqui que você executaria a validação de entrada básica e talvez uma validação mais complicada, como verificar a validade de uma combinação de usuário/senha com um servidor.

A forma como você notifica o usuário de um erro é específica do aplicativo. Você pode abrir um UIAlertView ou mostrar uma dica.

Resumo

Este artigo abordou muitas informações sobre MonoTouch.Dialog. Discutiu os conceitos básicos de como o MT. D funciona e aborda os vários componentes que compõem MT.D. Ele também mostrou a ampla matriz de elementos e personalizações de tabela compatíveis com MT. D e discutiu como MT. D pode ser estendido com elementos personalizados. Além disso, ele explicou o suporte a JSON no MT. D que permite criar elementos dinamicamente a partir de JSON.