Windows no Xamarin.Mac
Este artigo aborda o trabalho com janelas e painéis em um aplicativo Xamarin.Mac. Ele descreve a criação de janelas e painéis no Xcode e no Interface Builder, carregando-os a partir de storyboards e arquivos .xib e trabalhando com eles programaticamente.
Ao trabalhar com C# e .NET em um aplicativo Xamarin.Mac, você tem acesso ao mesmo Windows e Painéis que um desenvolvedor trabalhando e Objective-CXcode faz. Como o Xamarin.Mac se integra diretamente ao Xcode, você pode usar o Construtor de Interfaces do Xcode para criar e manter seu Windows e Painéis (ou, opcionalmente, criá-los diretamente no código C#).
Com base em sua finalidade, um aplicativo Xamarin.Mac pode apresentar um ou mais Windows na tela para gerenciar e coordenar as informações que exibe e com as quais trabalha. As principais funções de uma janela são:
- Para fornecer uma área na qual os Modos de Exibição e Controles possam ser colocados e gerenciados.
- Para aceitar e responder a eventos em resposta à interação do usuário com o teclado e o mouse.
O Windows pode ser usado em um estado Modeless (como um editor de texto que pode ter vários documentos abertos ao mesmo tempo) ou Modal (como uma caixa de diálogo Export que deve ser descartada antes que o aplicativo possa continuar).
Os painéis são um tipo especial de Janela (uma subclasse da classe base NSWindow
), que normalmente servem a uma função auxiliar em um aplicativo, como janelas de utilitários como Inspetores de formato de texto e Seletor de Cores do sistema.
Neste artigo, abordaremos os conceitos básicos de como trabalhar com Windows e Painéis em um aplicativo Xamarin.Mac. É altamente recomendável que você trabalhe primeiro no artigo Olá, Mac, especificamente nas seções Introdução ao Xcode e ao Construtor de Interface e Saídas e Ações, pois ele aborda os principais conceitos e técnicas que usaremos neste artigo.
Você pode querer dar uma olhada na seção Expondo classes C# / métodos para Objective-C do documento Xamarin.Mac Internals também, ele explica os Register
comandos e Export
usados para conectar suas classes C# a Objective-C objetos e elementos da interface do usuário.
Introdução ao Windows
Como dito acima, uma Janela fornece uma área na qual Exibições e Controles podem ser colocados e gerenciados e responde a eventos com base na interação do usuário (via teclado ou mouse).
De acordo com a Apple, existem cinco tipos principais de Windows em um aplicativo macOS:
- Janela Documento - Uma janela de documento contém dados de usuário baseados em arquivo, como uma planilha ou um documento de texto.
- Janela do aplicativo - Uma janela do aplicativo é a janela principal de um aplicativo que não é baseado em documento (como o aplicativo Calendário em um Mac).
- Painel - Um painel flutua acima de outras janelas e fornece ferramentas ou controles com os quais os usuários podem trabalhar enquanto os documentos estão abertos. Em alguns casos, um painel pode ser translúcido (como ao trabalhar com gráficos grandes).
- Caixa de diálogo - Uma caixa de diálogo aparece em resposta a uma ação do usuário e normalmente fornece maneiras pelas quais os usuários podem concluir a ação. Uma caixa de diálogo requer uma resposta do usuário antes de ser fechada. (Veja Trabalhando com caixas de diálogo)
- Alertas - Um alerta é um tipo especial de caixa de diálogo que aparece quando ocorre um problema grave (como um erro) ou como um aviso (como a preparação para excluir um arquivo). Como um alerta é uma caixa de diálogo, ele também requer uma resposta do usuário antes de poder ser fechado. (Veja Trabalhando com alertas)
Para obter mais informações, consulte a seção Sobre o Windows dos temas de design do macOS da Apple.
Janelas principal, chave e inativa
O Windows em um aplicativo Xamarin.Mac pode parecer e se comportar de forma diferente com base em como o usuário está interagindo com eles no momento. A principal Janela de Documento ou Aplicativo que atualmente é o foco da atenção do usuário é chamada de Janela Principal. Na maioria dos casos, essa janela também será a janela de chave (a janela que está aceitando a entrada do usuário no momento). Mas esse nem sempre é o caso, por exemplo, um Seletor de Cores pode estar aberto e ser a janela Chave com a qual o usuário está interagindo para alterar o estado de um item na Janela de Documento (que ainda seria a Janela Principal).
As janelas principal e chave (se estiverem separadas) estão sempre ativas, as janelas inativas são janelas abertas que não estão em primeiro plano. Por exemplo, um aplicativo editor de texto poderia ter mais de um documento aberto ao mesmo tempo, apenas a Janela Principal estaria ativa, todos os outros estariam inativos.
Para obter mais informações, consulte a seção Sobre o Windows dos temas de design do macOS da Apple.
Nomeando janelas
Uma Janela pode exibir uma Barra de Título e, quando o Título é exibido, geralmente é o nome do aplicativo, o nome do documento que está sendo trabalhado ou a função da janela (como Inspetor). Alguns aplicativos não exibem uma Barra de Título porque são reconhecíveis à vista e não funcionam com documentos.
A Apple sugere as seguintes diretrizes:
- Use o nome do aplicativo para o título de uma janela principal que não seja do documento.
- Nomeie uma nova janela
untitled
de documento . Para o primeiro novo documento, não acrescente um número ao Título (comountitled 1
). Se o usuário criar outro novo documento antes de salvar e titular o primeiro, chame essa janelauntitled 2
,untitled 3
etc.
Para obter mais informações, consulte a seção Nomeando o Windows dos temas de design do macOS da Apple.
Janelas de tela cheia
No macOS, a janela de um aplicativo pode ficar em tela cheia escondendo tudo, incluindo a Barra de Menus do Aplicativo (que pode ser revelada movendo o cursor para o topo da tela) para fornecer interação livre de distrações com seu conteúdo.
A Apple sugere as seguintes diretrizes:
- Determine se faz sentido uma janela ficar em tela cheia. Os aplicativos que fornecem interações breves (como uma calculadora) não devem fornecer um modo de tela cheia.
- Mostre a barra de ferramentas se a tarefa de tela inteira exigir. Normalmente, a barra de ferramentas fica oculta no modo de tela cheia.
- A janela de tela cheia deve ter todos os recursos que os usuários precisam para concluir a tarefa.
- Se possível, evite a interação com o Finder enquanto o usuário estiver em uma janela de tela cheia.
- Aproveite o aumento do espaço na tela sem desviar o foco da tarefa principal.
Para obter mais informações, consulte a seção Windows em tela cheia dos temas de design do macOS da Apple.
Painéis
Um Painel é uma janela auxiliar que contém controles e opções que afetam o documento ativo ou a seleção (como o Seletor de Cores do sistema):
Os painéis podem ser específicos do aplicativo ou de todo o sistema. Os painéis específicos do aplicativo flutuam sobre a parte superior das janelas de documento do aplicativo e desaparecem quando o aplicativo está em segundo plano. Os painéis de todo o sistema (como o painel Fontes) flutuam sobre todas as janelas abertas, independentemente do aplicativo.
A Apple sugere as seguintes diretrizes:
- Em geral, use um painel padrão, painéis transparentes só devem ser usados com moderação e para tarefas graficamente intensivas.
- Considere o uso de um painel para dar aos usuários acesso fácil a controles ou informações importantes que afetam diretamente suas tarefas.
- Ocultar e mostrar painéis conforme necessário.
- Os painéis devem sempre incluir a barra de título.
- Os painéis não devem incluir um botão de minimização ativo.
Inspectores
A maioria dos aplicativos macOS modernos apresenta controles auxiliares e opções que afetam o documento ativo ou a seleção como Inspetores que fazem parte da Janela Principal (como o aplicativo Páginas mostrado abaixo), em vez de usar o Painel do Windows:
Para obter mais informações, consulte a seção Painéis dos temas de design do macOS da Apple.
Criando e mantendo janelas no Xcode
Ao criar um novo aplicativo Xamarin.Mac Cocoa, você obtém uma janela padrão em branco por padrão. Essa janela é definida em um .storyboard
arquivo incluído automaticamente no projeto. Para editar o design do Windows, no Gerenciador de Soluções, clique duas vezes no Main.storyboard
arquivo:
Isso abrirá o design da janela no Construtor de Interfaces do Xcode:
No Inspetor de Atributos, há várias propriedades que você pode usar para definir e controlar sua janela:
- Título - Este é o texto que será exibido na barra de título da janela.
- Salvamento automático - Esta é a chave que será usada para identificar a janela quando sua posição e configurações forem salvas automaticamente.
- Barra de título - A janela exibe uma barra de título.
- Título e Barra de Ferramentas Unificados - Se a janela incluir uma Barra de Ferramentas, ela deverá fazer parte da barra de título.
- Visualização de conteúdo de tamanho completo - Permite que a área de conteúdo da janela fique sob a barra de título.
- Sombra - A janela tem uma sombra.
- Texturizadas - As janelas texturizadas podem usar efeitos (como vibração) e podem ser movidas arrastando para qualquer lugar do corpo.
- Fechar - A janela tem um botão Fechar .
- Minimizar - A janela tem um botão minimizar.
- Redimensionar - A janela tem um controle de redimensionamento.
- Botão da barra de ferramentas - A janela tem um botão ocultar/mostrar a barra de ferramentas.
- Restaurável - A posição e as configurações da janela são salvas e restauradas automaticamente.
- Visível na inicialização - A janela é mostrada automaticamente quando o
.xib
arquivo é carregado. - Ocultar ao desativar - A janela fica oculta quando o aplicativo entra em segundo plano.
- Liberar quando fechado - A janela é removida da memória quando é fechada.
- Sempre exibir dicas de ferramentas - As dicas de ferramentas são exibidas constantemente.
- Recalcula o loop de exibição - A ordem de exibição é recalculada antes que a janela seja desenhada.
- Spaces, Exposé e Cycling - Todos definem como a janela se comporta nesses ambientes macOS.
- Tela cheia - Determina se essa janela pode entrar no modo de tela cheia.
- Animação - Controla o tipo de animação disponível para a janela.
- Aparência - Controla a aparência da janela. Por enquanto há apenas uma aparição, Aqua.
Consulte a documentação de Introdução ao Windows e NSWindow da Apple para obter mais detalhes.
Definindo o tamanho e o local padrão
Para definir a posição inicial da janela e controlar seu tamanho, alterne para o Inspetor de tamanho:
A partir daqui, você pode definir o tamanho inicial da janela, dar-lhe um tamanho mínimo e máximo, definir a localização inicial na tela e controlar as bordas ao redor da janela.
Definindo um controlador de janela principal personalizado
Para poder criar Outlets e Actions para expor elementos da interface do usuário ao código C#, o aplicativo Xamarin.Mac precisará estar usando um Controlador de Janela Personalizado.
Faça o seguinte:
Abra o Storyboard do aplicativo no Construtor de Interfaces do Xcode.
Selecione o na superfície de
NSWindowController
design.Alterne para o modo de exibição Inspetor de Identidade e digite
WindowController
como o Nome da classe:Salve suas alterações e retorne ao Visual Studio para Mac para sincronizar.
Um
WindowController.cs
arquivo será adicionado ao seu projeto no Gerenciador de Soluções no Visual Studio para Mac:Reabra o Storyboard no Construtor de Interfaces do Xcode.
O
WindowController.h
arquivo estará disponível para uso:
Adicionando elementos da interface do usuário
Para definir o conteúdo de uma janela, arraste os controles do Inspetor de Biblioteca para o Editor de Interface. Consulte nossa documentação de Introdução ao Xcode e ao Construtor de Interface para obter mais informações sobre como usar o Construtor de Interface para criar e habilitar controles.
Como exemplo, vamos arrastar uma barra de ferramentas do Inspetor de biblioteca para a janela no Editor de interface:
Em seguida, arraste uma Vista de Texto e dimensione-a para preencher a área sob a barra de ferramentas:
Como queremos que o Modo de Exibição de Texto diminua e cresça à medida que o tamanho da janela muda, vamos alternar para o Editor de Restrições e adicionar as seguintes restrições:
Ao clicar nos quatro feixes de I vermelhos na parte superior do editor e clicar em Adicionar 4 restrições, estamos dizendo à exibição de texto para manter as coordenadas X,Y dadas e aumentar ou diminuir horizontal e verticalmente à medida que a janela é redimensionada.
Finalmente, exponha a Exibição de texto ao código usando uma tomada (certificando-se de selecionar o ViewController.h
arquivo):
Salve suas alterações e volte para o Visual Studio para Mac para sincronizar com o Xcode.
Para obter mais informações sobre como trabalhar com Outlets e Ações, consulte nossa documentação de Outlet e Ação.
Fluxo de trabalho de janela padrão
Para qualquer janela que você criar e trabalhar com seu aplicativo Xamarin.Mac, o processo é basicamente o mesmo que acabamos de fazer acima:
- Para novas janelas que não são o padrão adicionado automaticamente ao seu projeto, adicione uma nova definição de janela ao projeto. Isso será discutido em detalhes a seguir.
- Clique duas vezes no
Main.storyboard
arquivo para abrir o design da janela para edição no Construtor de Interfaces do Xcode. - Arraste uma nova janela para o design da interface do usuário e conecte a janela à janela principal usando o Segues (para obter mais informações, consulte a seção Segues da nossa documentação Trabalhando com storyboards).
- Defina todas as propriedades de janela necessárias no Inspetor de Atributos e no Inspetor de Tamanho.
- Arraste os controles necessários para criar sua interface e configure-os no Inspetor de Atributos.
- Use o Inspetor de Tamanho para manipular o redimensionamento dos elementos da interface do usuário.
- Exponha os elementos da interface do usuário da janela ao código C# por meio de Saídas e Ações.
- Salve suas alterações e volte para o Visual Studio para Mac para sincronizar com o Xcode.
Agora que temos uma janela básica criada, veremos os processos típicos que um aplicativo Xamarin.Mac faz ao trabalhar com janelas.
Exibindo a janela padrão
Por padrão, um novo aplicativo Xamarin.Mac exibirá automaticamente a janela definida no MainWindow.xib
arquivo quando ele for iniciado:
Como modificamos o design dessa janela acima, ela agora inclui um controle padrão da Barra de Ferramentas e do Modo de Exibição de Texto. A seção a Info.plist
seguir no arquivo é responsável por exibir essa janela:
A lista suspensa Interface Principal é usada para selecionar o Storyboard que será usado como a interface do usuário principal do aplicativo (neste caso Main.storyboard
).
Um controlador de exibição é adicionado automaticamente ao projeto para controlar as janelas principais que são exibidas (junto com sua exibição principal). Ele é definido no ViewController.cs
arquivo e anexado ao proprietário do arquivo no Construtor de Interface sob o Inspetor de identidade:
Para nossa janela, gostaríamos que ela tivesse um título de untitled
quando ela é aberta pela primeira vez, então vamos substituir o ViewWillAppear
método no ViewController.cs
para se parecer com o seguinte:
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set Window Title
this.View.Window.Title = "untitled";
}
Observação
A propriedade da Title
janela é definida no ViewWillAppear
método em vez do método porque, embora o modo de ViewDidLoad
exibição possa ser carregado na memória, ele ainda não está totalmente instanciado. Acessando a Title
ViewDidLoad
propriedade no método, teremos uma null
exceção, já que a janela ainda não foi construída e conectada ao imóvel.
Fechando programaticamente uma janela
Pode haver momentos em que você deseja fechar programaticamente uma janela em um aplicativo Xamarin.Mac, além de fazer com que o usuário clique no botão Fechar da janela ou use um item de menu. O macOS fornece duas maneiras diferentes de fechar um NSWindow
programaticamente: PerformClose
e Close
.
ExecutarFechar
Chamar o PerformClose
método de an NSWindow
simula o usuário clicar no botão Fechar da janela, destacando momentaneamente o botão e, em seguida, fechando a janela.
Se o aplicativo implementar o NSWindow
evento 's WillClose
, ele será gerado antes que a janela seja fechada. Se o evento retornar false
, a janela não será fechada. Se a janela não tiver um botão Fechar ou não puder ser fechada por qualquer motivo, o sistema operacional emitirá o som de alerta.
Por exemplo:
MyWindow.PerformClose(this);
Tentaria fechar a MyWindow
NSWindow
instância. Se for bem-sucedido, a janela será fechada, caso contrário, o som de alerta será emitido e o permanecerá aberto.
Fechar
Chamar o Close
método de an NSWindow
não simula o usuário clicando no botão Fechar da janela destacando momentaneamente o botão, ele simplesmente fecha a janela.
Uma janela não precisa estar visível para ser fechada e uma NSWindowWillCloseNotification
notificação será postada na Central de Notificações padrão para a janela que está sendo fechada.
O Close
método difere de duas maneiras importantes do PerformClose
método:
- Não tenta levantar o
WillClose
evento. - Ele não simula o usuário clicando no botão Fechar destacando momentaneamente o botão.
Por exemplo:
MyWindow.Close();
Queria fechar a MyWindow
NSWindow
instância.
Conteúdo modificado do Windows
No macOS, a Apple forneceu uma maneira de informar ao usuário que o conteúdo de uma janela (NSWindow
) foi modificado pelo usuário e precisa ser salvo. Se a Janela contiver conteúdo modificado, um pequeno ponto preto será exibido no widget Fechar :
Se o usuário tentar fechar a Janela ou sair do Aplicativo Mac enquanto houver alterações não salvas no conteúdo da Janela, você deverá apresentar uma Caixa de Diálogo ou Planilha Modal e permitir que o usuário salve suas alterações primeiro:
Marcando uma janela como modificada
Para marcar uma janela como tendo conteúdo modificado, use o seguinte código:
// Mark Window content as modified
Window.DocumentEdited = true;
E depois que a alteração for salva, limpe o sinalizador modificado usando:
// Mark Window content as not modified
Window.DocumentEdited = false;
Salvando alterações antes de fechar uma janela
Para observar o usuário fechando uma janela e permitindo que ele salve o conteúdo modificado com antecedência, você precisará criar uma subclasse de NSWindowDelegate
e substituir seu WindowShouldClose
método. Por exemplo:
using System;
using AppKit;
using System.IO;
using Foundation;
namespace SourceWriter
{
public class EditorWindowDelegate : NSWindowDelegate
{
#region Computed Properties
public NSWindow Window { get; set;}
#endregion
#region constructors
public EditorWindowDelegate (NSWindow window)
{
// Initialize
this.Window = window;
}
#endregion
#region Override Methods
public override bool WindowShouldClose (Foundation.NSObject sender)
{
// is the window dirty?
if (Window.DocumentEdited) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "Save changes to document before closing window?",
MessageText = "Save Document",
};
alert.AddButton ("Save");
alert.AddButton ("Lose Changes");
alert.AddButton ("Cancel");
var result = alert.RunSheetModal (Window);
// Take action based on result
switch (result) {
case 1000:
// Grab controller
var viewController = Window.ContentViewController as ViewController;
// Already saved?
if (Window.RepresentedUrl != null) {
var path = Window.RepresentedUrl.Path;
// Save changes to file
File.WriteAllText (path, viewController.Text);
return true;
} else {
var dlg = new NSSavePanel ();
dlg.Title = "Save Document";
dlg.BeginSheet (Window, (rslt) => {
// File selected?
if (rslt == 1) {
var path = dlg.Url.Path;
File.WriteAllText (path, viewController.Text);
Window.DocumentEdited = false;
viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = dlg.Url;
Window.Close();
}
});
return true;
}
return false;
case 1001:
// Lose Changes
return true;
case 1002:
// Cancel
return false;
}
}
return true;
}
#endregion
}
}
Use o código a seguir para anexar uma instância desse delegado à janela:
// Set delegate
Window.Delegate = new EditorWindowDelegate(Window);
Salvando alterações antes de fechar o aplicativo
Finalmente, seu aplicativo Xamarin.Mac deve verificar se algum de seus Windows contém conteúdo modificado e permitir que o usuário salve as alterações antes de sair. Para fazer isso, edite seu AppDelegate.cs
arquivo, substitua o ApplicationShouldTerminate
método e faça com que ele tenha a seguinte aparência:
public override NSApplicationTerminateReply ApplicationShouldTerminate (NSApplication sender)
{
// See if any window needs to be saved first
foreach (NSWindow window in NSApplication.SharedApplication.Windows) {
if (window.Delegate != null && !window.Delegate.WindowShouldClose (this)) {
// Did the window terminate the close?
return NSApplicationTerminateReply.Cancel;
}
}
// Allow normal termination
return NSApplicationTerminateReply.Now;
}
Trabalhando com várias janelas
A maioria dos aplicativos Mac baseados em documentos pode editar vários documentos ao mesmo tempo. Por exemplo, um editor de texto pode ter vários arquivos de texto abertos para edição ao mesmo tempo. Por padrão, um novo aplicativo Xamarin.Mac tem um menu Arquivo com um Novo item conectado automaticamente à newDocument:
Ação.
O código abaixo ativará esse novo item e permitirá que o usuário abra várias cópias da Janela Principal para editar vários documentos de uma só vez.
Edite o AppDelegate.cs
arquivo e adicione a seguinte propriedade computada:
public int UntitledWindowCount { get; set;} =1;
Use isso para rastrear o número de arquivos não salvos para que possamos dar feedback ao usuário (de acordo com as diretrizes da Apple, conforme discutido acima).
Em seguida, adicione o seguinte método:
[Export ("newDocument:")]
void NewDocument (NSObject sender) {
// Get new window
var storyboard = NSStoryboard.FromName ("Main", null);
var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;
// Display
controller.ShowWindow(this);
// Set the title
controller.Window.Title = (++UntitledWindowCount == 1) ? "untitled" : string.Format ("untitled {0}", UntitledWindowCount);
}
Este código cria uma nova versão do nosso Controlador de Janela, carrega a nova Janela, torna-a a Janela Principal e Chave e define o título. Agora, se executarmos nosso aplicativo e selecionarmos Novo no menu Arquivo , uma nova janela do editor será aberta e exibida:
Se abrirmos o menu do Windows , você poderá ver que o aplicativo está rastreando e manipulando automaticamente nossas janelas abertas:
Para obter mais informações sobre como trabalhar com menus em um aplicativo Xamarin.Mac, consulte nossa documentação Trabalhando com menus .
Obtendo a janela ativa no momento
Em um aplicativo Xamarin.Mac que pode abrir várias janelas (documentos), há momentos em que você precisará obter a janela atual, mais alta (a janela chave). O código a seguir retornará a janela de chave:
var window = NSApplication.SharedApplication.KeyWindow;
Ele pode ser chamado em qualquer classe ou método que precise acessar a janela de chave atual. Se nenhuma janela estiver aberta no momento, ela retornará null
.
Acessando todas as janelas do aplicativo
Pode haver momentos em que você precise acessar todas as janelas que seu aplicativo Xamarin.Mac tem abertas no momento. Por exemplo, para ver se um arquivo que o usuário deseja abrir já está aberto em uma janela de saída.
O NSApplication.SharedApplication
mantém uma Windows
propriedade que contém uma matriz de todas as janelas abertas em seu aplicativo. Você pode iterar sobre essa matriz para acessar todas as janelas atuais do aplicativo. Por exemplo:
// Is the file already open?
for(int n=0; n<NSApplication.SharedApplication.Windows.Length; ++n) {
var content = NSApplication.SharedApplication.Windows[n].ContentViewController as ViewController;
if (content != null && path == content.FilePath) {
// Bring window to front
NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);
return true;
}
}
No código de exemplo, estamos convertendo cada janela retornada para a classe personalizada ViewController
em nosso aplicativo e testando o valor de uma propriedade personalizada Path
em relação ao caminho de um arquivo que o usuário deseja abrir. Se o arquivo já está aberto, estamos trazendo essa janela para a frente.
Ajustando o tamanho da janela no código
Há momentos em que o aplicativo precisa redimensionar uma janela no código. Para redimensionar e reposicionar uma janela, ajuste sua Frame
propriedade. Ao ajustar o tamanho de uma janela, você geralmente precisa também ajustar sua origem, para manter a janela no mesmo local por causa do sistema de coordenadas do macOS.
Ao contrário do iOS, onde o canto superior esquerdo representa (0,0), o macOS usa um sistema de coordenadas matemáticas onde o canto inferior esquerdo da tela representa (0,0). No iOS, as coordenadas aumentam à medida que você se move para baixo em direção à direita. No macOS, as coordenadas aumentam de valor para cima à direita.
O código de exemplo a seguir redimensiona uma janela:
nfloat y = 0;
// Calculate new origin
y = Frame.Y - (768 - Frame.Height);
// Resize and position window
CGRect frame = new CGRect (Frame.X, y, 1024, 768);
SetFrame (frame, true);
Importante
Ao ajustar o tamanho e o local de uma janela no código, você precisa respeitar os tamanhos mínimo e máximo definidos no Construtor de Interfaces. Isso não será automaticamente honrado e você poderá tornar a janela maior ou menor do que esses limites.
Monitorando alterações no tamanho da janela
Pode haver momentos em que você precise monitorar as alterações no tamanho de uma janela dentro do seu aplicativo Xamarin.Mac. Por exemplo, para redesenhar o conteúdo para se ajustar ao novo tamanho.
Para monitorar as alterações de tamanho, primeiro verifique se você atribuiu uma classe personalizada para o Controlador de Janela no Construtor de Interfaces do Xcode. Por exemplo, MasterWindowController
no seguinte:
Em seguida, edite a classe personalizada Window Controller e monitore o DidResize
evento na Janela do Controller para ser notificado sobre alterações de tamanho dinâmico. Por exemplo:
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
Window.DidResize += (sender, e) => {
// Do something as the window is being live resized
};
}
Opcionalmente, você pode usar o evento para ser notificado DidEndLiveResize
somente depois que o usuário terminar de alterar o tamanho da janela. Por exemplo:
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
Window.DidEndLiveResize += (sender, e) => {
// Do something after the user's finished resizing
// the window
};
}
Definindo o título e o arquivo representado de uma janela
Ao trabalhar com janelas que representam documentos, tem uma DocumentEdited
propriedade que, NSWindow
se definida como true
exibe um pequeno ponto no botão Fechar para dar ao usuário uma indicação de que o arquivo foi modificado e deve ser salvo antes de fechar.
Vamos editar nosso ViewController.cs
arquivo e fazer as seguintes alterações:
public bool DocumentEdited {
get { return View.Window.DocumentEdited; }
set { View.Window.DocumentEdited = value; }
}
...
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set Window Title
this.View.Window.Title = "untitled";
View.Window.WillClose += (sender, e) => {
// is the window dirty?
if (DocumentEdited) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "We need to give the user the ability to save the document here...",
MessageText = "Save Document",
};
alert.RunModal ();
}
};
}
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Show when the document is edited
DocumentEditor.TextDidChange += (sender, e) => {
// Mark the document as dirty
DocumentEdited = true;
};
// Overriding this delegate is required to monitor the TextDidChange event
DocumentEditor.ShouldChangeTextInRanges += (NSTextView view, NSValue[] values, string[] replacements) => {
return true;
};
}
Também estamos monitorando o WillClose
evento na janela e verificando o estado do DocumentEdited
imóvel. Se for true
, precisamos dar ao usuário a capacidade de salvar as alterações no arquivo. Se executarmos nosso aplicativo e inserirmos algum texto, o ponto será exibido:
Se você tentar fechar a janela, receberá um alerta:
Se você estiver carregando um documento de um arquivo, defina o título da janela como o nome do arquivo usando o window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
método (dado que é uma cadeia de caracteres que representa o arquivo que path
está sendo aberto). Além disso, você pode definir a URL do arquivo usando o window.RepresentedUrl = url;
método.
Se a URL estiver apontando para um tipo de arquivo conhecido pelo sistema operacional, seu ícone será exibido na barra de título. Se o usuário clicar com o botão direito do mouse no ícone, o caminho para o arquivo será mostrado.
Edite o AppDelegate.cs
arquivo e adicione o seguinte método:
[Export ("openDocument:")]
void OpenDialog (NSObject sender)
{
var dlg = NSOpenPanel.OpenPanel;
dlg.CanChooseFiles = true;
dlg.CanChooseDirectories = false;
if (dlg.RunModal () == 1) {
// Nab the first file
var url = dlg.Urls [0];
if (url != null) {
var path = url.Path;
// Get new window
var storyboard = NSStoryboard.FromName ("Main", null);
var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;
// Display
controller.ShowWindow(this);
// Load the text into the window
var viewController = controller.Window.ContentViewController as ViewController;
viewController.Text = File.ReadAllText(path);
viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = url;
}
}
}
Agora, se executarmos nosso aplicativo, selecione Abrir... no menu Arquivo, selecione um arquivo de texto na caixa de diálogo Abrir e abra-o:
O arquivo será exibido e o título será definido com o ícone do arquivo:
Adicionando uma nova janela a um projeto
Além da janela principal do documento, um aplicativo Xamarin.Mac pode precisar exibir outros tipos de janelas para o usuário, como Preferências ou Painéis do Inspetor.
Para adicionar uma nova janela, faça o seguinte:
No Gerenciador de Soluções, clique duas vezes no
Main.storyboard
arquivo para abri-lo para edição no Construtor de Interfaces do Xcode.Arraste um novo Controlador de Janela da Biblioteca e solte-o na Superfície de Design:
No Inspetor de Identidade, insira
PreferencesWindow
a ID do Storyboard:Projete sua interface:
Abra o Menu do aplicativo (
MacWindows
), selecione Preferências..., clique com a tecla Control pressionada e arraste para a nova janela:Selecione Mostrar no menu pop-up.
Salve suas alterações e retorne ao Visual Studio para Mac para sincronizar com o Xcode.
Se executarmos o código e selecionarmos as Preferências... no Menu do aplicativo, a janela será exibida:
Trabalhando com painéis
Como dito no início deste artigo, um painel flutua acima de outras janelas e fornece ferramentas ou controles com os quais os usuários podem trabalhar enquanto os documentos estão abertos.
Assim como qualquer outro tipo de janela que você cria e trabalha em seu aplicativo Xamarin.Mac, o processo é basicamente o mesmo:
- Adicione uma nova definição de janela ao projeto.
- Clique duas vezes no
.xib
arquivo para abrir o design da janela para edição no Construtor de Interfaces do Xcode. - Defina todas as propriedades de janela necessárias no Inspetor de Atributos e no Inspetor de Tamanho.
- Arraste os controles necessários para criar sua interface e configure-os no Inspetor de Atributos.
- Use o Inspetor de Tamanho para manipular o redimensionamento dos elementos da interface do usuário.
- Exponha os elementos da interface do usuário da janela ao código C# por meio de Saídas e Ações.
- Salve suas alterações e volte para o Visual Studio para Mac para sincronizar com o Xcode.
No Inspetor de Atributos, você tem as seguintes opções específicas para Painéis:
- Estilo - Permite ajustar o estilo do painel de: Painel Normal (parece uma janela padrão), Painel de Utilitários (tem uma barra de título menor), Painel HUD (é translúcido e a barra de título faz parte do plano de fundo).
- Não Ativando - Determina no painel torna-se a janela chave.
- Modalidade de Documento - Se o Modo de Documento , o painel flutuará apenas acima das janelas do aplicativo, caso contrário, flutuará acima de tudo.
Para adicionar um novo Painel, faça o seguinte:
No Gerenciador de Soluções, clique com o botão direito do mouse no Projeto e selecione Adicionar>Novo Arquivo....
Na caixa de diálogo Novo arquivo, selecione Xamarin.Mac>Cocoa Window with Controller:
Digite
DocumentPanel
para o Nome e clique no botão Novo.Clique duas vezes no
DocumentPanel.xib
arquivo para abri-lo para edição no Construtor de Interfaces:Exclua a Janela existente e arraste um Painel do Inspetor de Biblioteca no Editor de Interface:
Conecte o painel à saída da janela - Proprietário - do arquivo:
Alterne para o Inspetor de Identidade e defina a classe do Painel como
DocumentPanel
:Salve suas alterações e retorne ao Visual Studio para Mac para sincronizar com o Xcode.
Edite o
DocumentPanel.cs
arquivo e altere a definição de classe para o seguinte:public partial class DocumentPanel : NSPanel
Salve as alterações no arquivo.
Edite o AppDelegate.cs
arquivo e faça com que o DidFinishLaunching
método tenha a seguinte aparência:
public override void DidFinishLaunching (NSNotification notification)
{
// Display panel
var panel = new DocumentPanelController ();
panel.Window.MakeKeyAndOrderFront (this);
}
Se executarmos nosso aplicativo, o painel será exibido:
Importante
O painel do Windows foi preterido pela Apple e deve ser substituído pelo Inspector Interfaces.
Resumo
Este artigo deu uma olhada detalhada no trabalho com o Windows e painéis em um aplicativo Xamarin.Mac. Vimos os diferentes tipos e usos do Windows e Painéis, como criar e manter o Windows e Painéis no Construtor de Interfaces do Xcode e como trabalhar com o Windows e Painéis em código C#.