Transferência de dados com vinculação de dados

Concluído

Nesta lição, exploramos como você pode usar a vinculação de dados para entrada de dados, mostrando e ocultando partes da interface do usuário com base no estado do aplicativo. Você também vai se familiarizar com o padrão completo INotifyPropertyChanged .

Vamos expandir nossa demonstração existente com uma saudação amigável que se parece com esta.

Screenshot of sample app with a name entry field and submit button.

Quando você seleciona o botão Enviar, o aplicativo exibirá uma simples saudação na parte superior.

Screenshot of sample app showing

1. Abra a solução

Se você não tiver o Visual Studio aberto com o projeto criado durante a última lição, abra-o agora.

2. Criar a interface do usuário de entrada de dados

A interface do usuário de entrada de dados é simples: apenas um , a TextBoxe um , em um TextBlockButtonúnico layout horizontal no meio da tela. A maneira mais simples de colocar controles horizontalmente é usar um StackPanel, como este.

<StackPanel HorizontalAlignment="Center" 
            VerticalAlignment="Center" 
            Orientation="Horizontal">
    <TextBlock Margin="10" 
               VerticalAlignment="Center" 
               Text="Enter your name: "/>
    <TextBox Name="tbUserName" 
             Margin="10" 
             Width="150" 
             VerticalAlignment="Center"/>
    <Button Margin="10" 
            VerticalAlignment="Center" >Submit</Button>
</StackPanel>

Copie o código anterior e cole-o dentro da Grid tag de MainPage.xaml, abaixo do .TextBlock

3. Implementar e vincular a propriedade UserName

Vamos voltar nossa atenção para o código. Abra MainPage.xaml.cs (você pode pressionar F7 para alternar para o code-behind e Shift+F7 para voltar para o XAML). Crie uma propriedade simples chamada UserName.

public string UserName { get; set; }

Voltando ao MainPage.xaml, podemos criar a associação de dados entre essa propriedade recém-criada e o TextBox controle. Altere o controle adicionando o TextBoxText atributo, desta forma:

<TextBox Name="tbUserName" 
         Margin="10" 
         Width="150" 
         VerticalAlignment="Center" 
         Text="{x:Bind UserName, Mode=TwoWay}"/>

Nota

Certifique-se de não confundir o TextBlock e os TextBox controles aqui. Eles são muito semelhantes em XAML, mas se você vincular a propriedade TextBlocktext ao UserName , em vez do TextBox, o aplicativo não funcionará.

Com o código anterior, criamos uma ligação bidirecional entre a propriedade do TextBox e a TextUserName propriedade no código. Isso significa que sempre que o usuário inserir texto (e mover o foco para fora do TextBox), a UserName propriedade no código será alterada. Além disso, o texto do é definido como o valor armazenado na propriedade no início do aplicativo, ou sempre que geramos o evento com o TextBoxNotifyPropertyChangedpropertyName parâmetro ."UserName"UserName (Não faremos isso nesta lição.)

4. Crie o manipulador de cliques do botão Enviar

Em seguida, na superfície de design, clique duas vezes no botão Enviar . Isso criará e abrirá automaticamente um Button_Click evento no código. Button_Click não é um nome particularmente bom, então mude o nome do método para um mais expressivo OnSubmitClicked. Quando terminar de digitar, clique na lâmpada ao lado da OnSubmitClicked linha. Selecione Renomear 'Button_Clicked' para 'OnSubmitClicked' no menu. Voltando ao XAML, verifique se o XAML do botão agora tem esta aparência.

<Button Margin="10" 
        VerticalAlignment="Center" 
        Click="OnSubmitClicked">Submit</Button>

Voltando ao code-behind, vamos exibir uma caixa de diálogo simples quando o botão for pressionado. Adicione o seguinte código ao método OnSubmitClicked:

var dlg = new Windows.UI.Popups.MessageDialog($"Hello {UserName}!");
_ = dlg.ShowAsync();

Se você não estiver familiarizado com a sintaxe, ela é o equivalente "Hello " + UserName + "!" a $"Hello {Username}" ou String.Format("Hello {0}!", UserName). Esse recurso mais conciso e legível é chamado de interpolação de cadeia de caracteres e foi introduzido no C# 6.

A _ é uma variável de descarte . Ele é usado para indicar que o valor de retorno do ShowAsync método não é usado. O ShowAsync método retorna um objeto, que é um Task espaço reservado para uma tarefa que será concluída no futuro. No nosso caso, não precisamos esperar que a tarefa seja concluída, para que possamos descartar o valor de retorno.

5. Execute o aplicativo

Vamos conferir o que fizemos até agora! Execute o aplicativo pressionando F5 ou Ctrl+F5. Digite seu nome, selecione o botão Enviar e uma caixa de diálogo deve cumprimentá-lo.

Screenshot of sample app with new greeting dialog box that displays

6. Implementar a IsNameNeeded propriedade

Se você fechar a caixa de diálogo, ainda verá a parte de entrada de nome da interface do usuário exibida. Não é isso que queremos. Precisamos ocultar o formulário assim que ele for preenchido com sucesso. Então, vamos fazer isso como a próxima etapa usando a vinculação de dados.

Abra MainPage.xaml.cs e crie uma propriedade para indicar se ainda é necessário inserir o nome do usuário. Adicione o seguinte código dentro da MainPage classe:

private bool _isNameNeeded = true;

public bool IsNameNeeded
{
    get { return _isNameNeeded; }
    set
    {
        if (value != _isNameNeeded)
        {
            _isNameNeeded = value;
            PropertyChanged?.Invoke(
                this, new PropertyChangedEventArgs(nameof(IsNameNeeded)));
        }
    }
}

Esta é uma propriedade booleana bastante padrão com um campo de apoio e um valor padrão de true, até chegarmos ao setter. O setter de propriedade primeiro verifica se o novo valor é o mesmo que o antigo. Se for, não há necessidade de fazer nada. Se nada tiver mudado, você não quer embarcar em um longo processo de recalcular o layout e rerenderizar os controles. No entanto, se o valor da propriedade tiver sido alterado, você precisará informar a interface do usuário sobre isso, usando o PropertyChanged evento .

No código anterior, você pode ver o padrão padrão da interface INotifyPropertyChanged :

  • Verifique se o valor foi alterado.
  • Se tiver, defina o novo valor.
  • Notifique a interface do usuário.

Depois de notificar a interface do usuário (supondo que o modo de associação esteja definido como OneWay ou TwoWay), ela chama o getter da propriedade, recebe o novo valor e altera a interface do usuário de acordo.

7. Oculte o formulário após a seleção do botão Enviar

No nosso caso, queremos que o formulário de entrada de nome fique visível apenas até que o botão Enviar tenha sido selecionado. Em seguida, deve desaparecer ao mesmo tempo que a mensagem de saudação é mostrada. Vamos alterar o OnSubmitClicked método, adicionando este código no início:

if (string.IsNullOrEmpty(UserName))
{
    return;
}

IsNameNeeded = false;

Primeiro, uma verificação rápida é realizada, pois não aceitamos mais um nome de usuário vazio aqui. Depois que um nome é inserido, é definido como false, IsNameNeeded e o aplicativo continua exibindo a caixa de diálogo de mensagem. Definir o valor de IsNameNeeded gera o NotifyPropertyChanged evento e notifica a interface do usuário.

Agora terminamos com o código para ocultar a interface do usuário. Vamos voltar ao XAML!

No lado XAML, precisamos ocultar o , o , e o TextBlockTextBoxButton quando IsNameNeeded é falso. Ou podemos simplesmente esconder seu recipiente, o StackPanel, em uma etapa. Basta adicionar o Visibility atributo ao StackPanel, assim:

Visibility="{x:Bind IsNameNeeded, Mode=OneWay}"

Execute o aplicativo, insira seu nome no TextBoxe verifique se o formulário de entrada realmente desaparece quando você seleciona o botão Enviar .

8. Use a associação UI-to-UI para exibir a saudação

Vamos substituir o MessageDialog por um display mais permanente: um TextBlock no canto superior esquerdo. Adicione um novo TextBlock ao controle principal Grid no XAML.

<TextBlock Text="{x:Bind sys:String.Format('Hello {0}!',  tbUserName.Text), Mode=OneWay}" 
           HorizontalAlignment="Left" 
           VerticalAlignment="Top" 
           Margin="10"/>

Há muitas coisas novas acontecendo aqui. Vamos dissecar a vinculação do Text atributo!

Para avaliar o Text valor da propriedade no TextBlock, o sistema chama o método interno String.Format com a cadeia de caracteres "Hello {0}"de formato . O objeto a ser formatado tbUserName será tbUserName.Text (em outras palavras, a Text propriedade no controle). O modo da ligação é definido como OneWay, o que significa que receberá TextBlock dados da TextBoxpropriedade do .Text

Isso é chamado de associação UI-to-UI porque a origem e o destino da associação de dados estão na interface do usuário. Para vê-lo em ação, você precisa definir o namespace (que contém o sysSystem.Format método). Adicione a seguinte linha à marca raiz Page no XAML:

xmlns:sys="using:System"

Agora, se você executar o aplicativo, verá que a saudação é atualizada a cada pressionamento de teclas. Você nem precisa remover o foco do TextBox botão Enviar ou selecioná-lo!

Screenshot of sample app running with a name entry field and value entered of

Em um aplicativo do mundo real, a exibição do nome do usuário não aconteceria por meio da associação UI-to-UI. Você provavelmente se vincularia à DisplayName propriedade de uma User classe, ou algo semelhante.

9. Oculte a saudação até que a opção Enviar seja selecionada

Por mais legal que pareça ter a atualização de saudação enquanto digita, o "Olá!" O texto na inicialização pode parecer pouco profissional. É preferível que a saudação TextBlock permaneça invisível até que o botão Enviar seja selecionado.

Para calcular se a saudação está visível, use um método chamado GetGreetingVisibilitye adicione-o MainPage à classe.

public Visibility GetGreetingVisibility()
{
    return IsNameNeeded ? Visibility.Collapsed : Visibility.Visible;
}

Você pode notar que, ao ocultar o StackPanel, estávamos vinculando um valor à Visibility propriedade (que tem um bool tipo de UIElement.Visibility). Vincular o a um bool valor é tão comum que a Visibility Microsoft criou uma conversão padrão entre os dois, e é por isso que não obtivemos nenhum erro de conversão de tipo anteriormente. No entanto, essa conversão automática só funciona para propriedades, portanto, o GetGreetingVisibility() método deve retornar UIElement.Visibility em vez de um valor booleano.

Assim como acontece com as propriedades, precisamos usar o evento para notificar a interface do usuário quando quisermos que ela reavalie o PropertyChanged método. Então, vamos adicionar esta linha ao final do OnSubmitClicked método.

PropertyChanged?.Invoke(this, 
    new PropertyChangedEventArgs(nameof(GetGreetingVisibility)));

Como etapa final, execute realmente a vinculação adicionando o Visibility atributo à saudação TextBlock. Em MainPage.xaml, edite o TextBlock para que tenha esta aparência:

<TextBlock Text="{x:Bind sys:String.Format('Hello {0}!',  tbUserName.Text), Mode=OneWay}" 
           Visibility="{x:Bind GetGreetingVisibility(), Mode=OneWay}"
           HorizontalAlignment="Left" 
           VerticalAlignment="Top" 
           Margin="10"/>

Observe que não foi necessário adicionar referências de namespace à GetGreetingVisibility() chamada, porque ela é um membro da MainPage própria classe.

Finalmente, para parar de exibir o MessageDialog, comente as seguintes linhas do OnSubmitClicked método.

// var dlg = new Windows.UI.Popups.MessageDialog($"Hello {UserName}!");
// dlg.ShowAsync();

Agora você está pronto para executar o aplicativo e aproveitar suas mensagens de saudação.

Resumo

Nesta lição, você viu como a vinculação de dados facilita a transferência de dados entre a interface do usuário e seu código, ou entre dois elementos da interface do usuário. No entanto, havia muito código para escrever, especialmente ao invocar o PropertyChanged evento nos setters de propriedade. Na próxima lição, você criará uma classe auxiliar para simplificar o INotifyPropertyChanged uso do padrão.

Nesta lição, exploramos como você pode usar a vinculação de dados para entrada de dados, mostrando e ocultando seções da interface do usuário com base no estado do aplicativo. Você também se familiarizará com o padrão completo INotifyPropertyChanged e aprenderá mais sobre DataContexto .

Vamos expandir nossa demonstração existente com uma saudação amigável que se parece com esta.

Screenshot of sample app with a name entry field and submit button.

Quando você seleciona o botão Enviar, o aplicativo exibirá uma simples saudação na parte superior.

Screenshot of sample app showing

1. Crie um DataContext em toda a janela

Se você não tiver o Visual Studio aberto com o projeto criado durante a última lição, abra-o agora.

Na lição anterior, criamos uma classe dedicada Clock que estava sendo instanciada dentro do que exibia TextBlock o relógio. Essa Clock classe continha a lógica de negócios para o próprio relógio. No entanto, muitas vezes você precisa abranger muito mais funcionalidade para uma tela, e seria tedioso definir o DataContext para cada controle na interface do usuário.

Felizmente, DataContext foi projetado para que você possa aplicá-lo a toda a árvore XAML - ou apenas a uma parte dela. Um atributo chave é que ele é DataContext herdado em toda a árvore XAML, mas pode ser substituído a qualquer momento por uma subárvore específica.

Vamos ver isso na prática. Crie uma nova classe chamada MainWindowDataContext, e certifique-se de que a classe e seu construtor são públicos:

namespace DatabindingSampleWPF
{
    public class MainWindowDataContext
    {
        public MainWindowDataContext()
        {
        }
    }
}

Agora, defina uma instância dessa classe como a DataContext para todo Windowo . Em MainWindow.xaml, adicione isso logo após a tag de abertura Window :

<Window.DataContext>
    <local:MainWindowDataContext />
</Window.DataContext>

Neste ponto, o Visual Studio pode indicar que a classe DatabindingSampleWPF.MainWindowDataContext não existe. Isso ocorre porque o projeto não foi compilado desde que você adicionou essa classe. Você pode corrigir esse erro compilando seu projeto.

Vamos rever o que temos até agora. O DataContext é definido no Window nível (raiz). Esta instância de objeto será a DataContext para cada controle dentro do Window. A única exceção é a TextBlock exibição do relógio, que já tem seu próprio DataContext conjunto, substituindo assim o global DataContextherdado. Se isso TextBlock tivesse mais controles dentro dele na hierarquia, esses também herdariam o Clock objeto definido no DataContextTextBlockdo .

2. Criar a interface do usuário de entrada de dados

A interface do usuário de entrada de dados é simples: apenas um , um e um em um TextBlockTextBoxButton único layout horizontal no meio da tela. A maneira mais simples de colocar controles horizontalmente é usar um StackPanel, como este.

<StackPanel HorizontalAlignment="Center" 
            VerticalAlignment="Center" 
            Orientation="Horizontal">
    <TextBlock Margin="10" 
               VerticalAlignment="Center" 
               Text="Enter your name:"/>
    <TextBox Name="tbName" 
             Margin="10" 
             Width="150" 
             VerticalAlignment="Center"/>
    <Button Margin="10" 
            VerticalAlignment="Center">Submit</Button>
</StackPanel>

Copie o código anterior e cole-o dentro da Grid tag de MainPage.xaml, abaixo do .TextBlock

3. Implementar e vincular a propriedade UserName

Vamos voltar nossa atenção para o código. Abra MainWindowDataContext.cse crie uma nova propriedade chamada UserName.

public string? UserName { get; set; }

Voltando ao MainWindow.xaml, podemos criar a ligação de dados entre a UserName propriedade e o TextBox controle. Altere o controle adicionando o TextBoxText atributo, desta forma:

<TextBox Name="tbUserName" 
         Margin="10" 
         Width="150" 
         VerticalAlignment="Center" 
         Text="{Binding UserName, Mode=TwoWay}"/>

Nota

Certifique-se de não confundir o TextBlock e os TextBox controles aqui. Eles são muito semelhantes em XAML, mas se você vincular a propriedade TextBlocktext ao UserName , em vez do TextBox, o aplicativo não funcionará.

Com o código anterior, criamos uma ligação bidirecional entre a propriedade do TextBox e a TextUserName propriedade no código. Isso significa que sempre que o usuário inserir texto (e mover o foco para fora do TextBox), a UserName propriedade no código será alterada. Além disso, o texto do será definido como o valor armazenado na propriedade no início do aplicativo ou sempre que gerarmos o evento com o TextBoxNotifyPropertyChangedpropertyName parâmetro ."UserName"UserName (Não faremos isso nesta lição.)

Nota

No WPF, o modo de vinculação é determinado automaticamente para as situações mais comuns. Por exemplo, se você estiver vinculando à Text propriedade de um TextBox, o WPF definirá o modo de vinculação como TwoWay por padrão. Isso significa que poderíamos até ter ignorado a especificação do modo de vinculação aqui, e poderíamos ter acabado de escrever Text={Binding UserName}. Saiba mais sobre os modos de vinculação aqui.

4. Crie o manipulador de cliques do botão Enviar

Em seguida, na superfície de design, clique duas vezes no botão Enviar . Isso criará automaticamente um Button_Click evento e MainWindow.xaml.cs abrirá o arquivo. Button_Click não é um nome muito descritivo, portanto, altere o nome do método para OnSubmitClicked. Quando terminar de digitar, clique na dica da chave de fenda ao lado da OnSubmitClicked linha e selecione Renomear 'Button_Clicked' para 'OnSubmitClicked' no menu. Retorne ao XAML e verifique se o XAML do botão agora tem esta aparência:

<Button Margin="10" 
        VerticalAlignment="Center" 
        Click="OnSubmitClicked">Submit</Button>

Voltando ao code-behind, vamos exibir uma caixa de diálogo simples quando o botão for pressionado. Adicione uma propriedade de conveniência ao topo da MainWindow classe que nos permite acessar facilmente o objeto que está definido como o de todo MainWindowo MainWindowDataContextDataContext .

private MainWindowDataContext DC => (MainWindowDataContext)DataContext;

Em seguida, adicione o seguinte código ao OnSubmitClicked método:

MessageBox.Show($"Hello {DC.UserName}!");

O valor do texto inserido no TextBox é armazenado na MainWindowDataContext.UserName propriedade. A primeira linha armazena MainWindowDataContext uma referência ao objeto em uma variável temporária. A segunda linha exibe uma caixa de mensagem com a saudação.

Se você não estiver familiarizado com a sintaxe, ela é o equivalente "Hello " + UserName + "!" a $"Hello {Username}" ou String.Format("Hello {0}!", UserName). Essa sintaxe mais concisa e legível é chamada de interpolação de cadeia de caracteres e foi introduzida em C# 6.

5. Execute o aplicativo

Vamos testar o que fizemos até agora! Execute o aplicativo pressionando F5 ou Ctrl+F5. Digite seu nome, selecione o botão Enviar e uma caixa de diálogo deve cumprimentá-lo.

Screenshot of sample app with new greeting dialog box that displays

6. Implementar a IsNameNeeded propriedade

Observe que a parte da entrada de nome da interface do usuário ainda é exibida depois que o botão Enviar é pressionado. Precisamos ocultar o formulário depois que ele for preenchido com sucesso. Então, vamos fazer isso como a próxima etapa usando a vinculação de dados.

Primeiro, abra MainWindowDataContext.cs e faça MainWindowDataContext herdar de INotifyPropertyChanged, assim como fizemos com a Clock classe.

using System.ComponentModel;

public class MainWindowDataContext : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

Em seguida, crie uma propriedade para indicar se ainda é necessário inserir o nome do usuário. Adicione o seguinte código dentro da MainWindowDataContext classe:

private bool _isNameNeeded = true;

public bool IsNameNeeded
{
    get { return _isNameNeeded; }
    set
    {
        if (value != _isNameNeeded)
        {
            _isNameNeeded = value;
            PropertyChanged?.Invoke(
                this, new PropertyChangedEventArgs(nameof(IsNameNeeded)));
        }
    }
}

Esta é uma propriedade booleana bastante padrão com um campo de apoio e um valor padrão de true, até chegarmos ao setter. O setter de propriedade primeiro verifica se o novo valor é o mesmo que o antigo. Se for, não há necessidade de fazer nada. Se nada tiver mudado, você não quer embarcar em um longo processo de recalcular o layout e rerenderizar os controles. No entanto, se o valor da propriedade tiver sido alterado, você precisará informar a interface do usuário sobre isso, usando o PropertyChanged evento .

No código anterior, você pode ver o padrão padrão da interface INotifyPropertyChanged :

  • Verifique se o valor foi alterado.
  • Se tiver, defina o novo valor.
  • Notifique a interface do usuário.

Depois de notificar a interface do usuário (supondo que o modo de associação esteja definido como OneWay ou TwoWay), ela chama o getter da propriedade, recebe o novo valor e altera a interface do usuário de acordo.

7. Oculte o formulário após a seleção do botão Enviar

No nosso caso, queremos que o formulário de entrada de nome fique visível apenas até que o botão Enviar tenha sido selecionado. Em seguida, deve desaparecer ao mesmo tempo que a mensagem de saudação é mostrada. Vamos alterar o OnSubmitClicked método, adicionando este código no início:

if (string.IsNullOrWhiteSpace(DC.UserName))
{
    return;
}

DC.IsNameNeeded = false;

Primeiro, uma verificação rápida é realizada, pois não aceitamos mais um nome de usuário vazio aqui. Depois que um nome é inserido, é definido como false, IsNameNeeded e o aplicativo continua exibindo a caixa de diálogo de mensagem. Definir o valor de IsNameNeeded gera o NotifyPropertyChanged evento e notifica a interface do usuário.

Agora terminamos com o código para ocultar a interface do usuário. Vamos voltar ao XAML!

No lado XAML, precisamos ocultar o , o , e o TextBlockTextBoxButton quando IsNameNeeded é falso. Ou podemos simplesmente esconder seu recipiente, o StackPanel, em uma etapa. Adicione o Visibility atributo ao StackPanel, desta forma:

Visibility="{Binding IsNameNeeded, Converter={StaticResource BooleanToVisibilityConverter}}"

Esta ligação consiste em duas partes. A primeira parte especifica o caminho de ligação, que aponta para a IsNameNeededMainWindowDataContext propriedade do objeto que é definido como o de todo Windowo DataContext .

Mas a IsNameNeeded propriedade é um booleano, enquanto Visibility é do tipo System.Windows.Visibility, que é um enumarquivo . Precisamos fazer uma conversão entre os dois. Essa conversão é tão comum que o WPF tem uma classe auxiliar interna chamada BooleanToVisibilityConverter. Precisamos criar uma instância dessa classe e fazer referência a ela a partir da declaração vinculativa.

Instanciamos essa classe em XAML, como um recurso do Window objeto. Cada FrameworkElement um pode ter sua própria coleção de recursos, com uma chave identificando cada recurso na coleção. A BooleanToVisibilityConverter ligação anterior é essa chave, apontando para um BooleanToVisibilityConverter objeto dentro da coleção de recursos. Você pode definir a coleção de recursos adicionando o seguinte código ao Window, logo após a tag de abertura:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>

Execute o aplicativo, insira seu nome no TextBoxe verifique se o formulário de entrada realmente desaparece quando você seleciona o botão Enviar .

8. Use a associação UI-to-UI para exibir a saudação

Vamos substituir o MessageDialog por um display mais permanente: um TextBlock no canto superior esquerdo. Adicione um novo TextBlock ao controle principal Grid no XAML.

<TextBlock Text="{Binding Text, ElementName=tbName, StringFormat='Hello {0}!'}"
           HorizontalAlignment="Left" 
           VerticalAlignment="Top" 
           Margin="10"/>

Há várias novidades introduzidas neste novo TextBlock. Vamos dissecar a vinculação do Text atributo!

Para avaliar o Text valor da propriedade no TextBlock, o sistema chama o método interno String.Format com a cadeia de caracteres "Hello {0}"de formato . O objeto a ser formatado tbName será tbName.Text (em outras palavras, a Text propriedade no controle). O modo da ligação é automaticamente definido como OneWay, o que significa que receberá TextBlock dados da TextBoxpropriedade do .Text

Isso é chamado de associação UI-to-UI porque a origem e o destino da associação de dados estão na interface do usuário. Para vê-lo em ação, basta executar o aplicativo. Observe como a saudação é atualizada a cada pressionamento de teclas. Você nem precisa remover o foco do TextBox botão Enviar ou selecioná-lo!

Screenshot of sample app running with a name entry field and value entered of

Em um aplicativo do mundo real, a exibição do nome do usuário não aconteceria por meio da associação UI-to-UI. Você provavelmente se vincularia à DisplayName propriedade de uma User classe ou outra abordagem semelhante.

9. Oculte a saudação até que a opção Enviar seja selecionada

Por mais legal que pareça ter a atualização de saudação enquanto digita, o "Olá!" O texto na inicialização pode parecer pouco profissional. É preferível que a saudação TextBlock permaneça invisível até que o botão Enviar seja selecionado.

Para calcular se a saudação está visível, use uma propriedade chamada GreetingVisibility, e adicione-a MainWindowDataContext à classe.

public Visibility GreetingVisibility => IsNameNeeded ? Visibility.Collapsed : Visibility.Visible;

Você também precisará adicionar o System.Windows namespace ao usings in MainWindowDataContext .

Você deve se lembrar que anteriormente, quando estávamos escondendo o StackPanel, estávamos vinculando um valor à Visibility propriedade (que tem um bool tipo de System.Windows.Visibility). No entanto, podemos ignorar se BooleanToVisibilityConverter a fonte de vinculação já for do tipo de dados correto.

Como antes, precisamos usar o evento para notificar a interface do usuário quando quisermos que ela reavalie o PropertyChangedGreetingVisibility. Então, vamos adicionar esta linha ao final do if bloco no IsNameNeeded setter.

PropertyChanged?.Invoke(
    this, new PropertyChangedEventArgs(nameof(GreetingVisibility)));

Isso garante que, sempre IsNameNeeded que for alterado, haverá dois PropertyChanged eventos gerados: um para o imóvel em si, e outro para o IsNameNeeded imóvel GreetingVisibilitycalculado, que depende do IsNameNeeded.

Como etapa final, execute a vinculação adicionando o Visibility atributo à saudação TextBlock. No MainWindow.xaml, edite o TextBlock para que fique assim:

<TextBlock Text="{Binding Text, ElementName=tbName, StringFormat='Hello {0}!'}"
           Visibility="{Binding GreetingVisibility}"
           HorizontalAlignment="Left" 
           VerticalAlignment="Top" 
           Margin="10"/>

Finalmente, para parar de exibir o MessageBox, comente a seguinte linha do OnSubmitClicked método em MainWindow.xaml.cs.

// MessageBox.Show($"Hello {DC.UserName}!");

Agora você está pronto para executar o aplicativo e aproveitar suas mensagens de saudação.

Resumo

Nesta lição, você viu como a vinculação de dados facilita a transferência de dados entre a interface do usuário e seu código, ou entre dois elementos da interface do usuário. No entanto, havia muito código para escrever, especialmente ao invocar o PropertyChanged evento nos setters de propriedade. Na próxima lição, você criará uma classe auxiliar para simplificar o INotifyPropertyChanged uso do padrão.