Eu desenvolvi um aplicativo WPF que consiste em uma janela principal e dois controles de usuário. O primeiro controle de usuário contém um botão, e o segundo controle de usuário tem uma caixa de texto. A janela principal inclui um DataGrid.
Preciso configurar para que, quando eu inserir um valor na caixa de texto no segundo controle de usuário e clicar no botão no primeiro controle de usuário, o valor da caixa de texto seja adicionado ao DataGrid na janela principal.
Como posso conseguir isso?
Primeiro controle do usuário:
<UserControl ....>
<Grid>
<Button x:Name="btnAddDetails" Content="Add details" Width="170" Height="60" Click="btnAddDetails_Click"/>
</Grid>
</UserControl>
Segundo controle do usuário:
<UserControl ....>
<StackPanel>
<TextBox x:Name="txtName"/>
<TextBox x:Name="txtDesc"/>
<CheckBox x:Name="chkIsActive" Content="IsActive"/>
</StackPanel>
</UserControl>
Existem duas maneiras de desenvolver aplicativos em WPF: o padrão code-behind e o MVVM (Model, View, ViewModel), que é o recomendado.
Vou mostrar a você um passo a passo simples sobre como criar o que você deseja usando o padrão MVVM (maneira recomendada):
2- Crie o Modelo de Usuário:
3- Crie a classe RelayCommand para manipular o clique do botão Adicionar Usuário:
4- Adicione o MainVM:
5- Agora no arquivo xaml da MainWindow adicione estes dois namespaces:
nota: veja que adicionei o ViewModel na pasta ViewModels e o mesmo para o controle do usuário, embora seja um aplicativo simples que usei apenas para organizar meus arquivos.
5.1- então utilize os user controls criados (no mesmo arquivo xaml):
Nota: o exemplo foi testado antes de ser escrito, você pode encontrá-lo aqui: https://github.com/amuza2/100DaysOfCode/tree/main/Day93/WpfApp1/SimpleWpfApp
Explicando algumas ideias principais:
1- Vinculação de dados entre View (controle de usuário) e ViewModel (MainVM), como no FillUserDataUserControl,
Text = "{Binding CurrentUser.Name}"
que cria uma vinculação entre a propriedade Text da caixa de texto e aCurrentUser.Name
propriedade no ViewModel (MainVM).2- INotifyPropertyChanged : Tanto o modelo User quanto o MainViewModel implementam essa interface, que é crucial para a vinculação bidirecional. Quando uma propriedade muda, o
PropertyChanged
evento é levantado por meio doOnPropertyChanged()
método, alertando a UI para atualizar.3- DataContext : Em MainWindow.xaml, a linha
<Window.DataContext><viewmodels:MainVM /></Window.DataContext>
estabelece o ViewModel como a fonte de dados para todas as ligações na janela e seus controles filhos.Este sistema de ligação permite alterações na UI para atualizar o ViewModel (e vice-versa) sem escrever manipuladores de eventos explícitos e código de atualização da UI.
4- No ButtonUserControl.xaml,
Command="{Binding AddUserCommand}"
vincule a propriedade Command do botão à propriedade AddUserCommand no ViewModel (MainVM).RelayCommand
classe implementa aICommand
interface, que define o contrato para comandos no WPF.O Commandmanager no RelayCommand se conecta ao CommandManager do WPF, que chama automaticamente CanExecute quando os estados de entrada mudam (como quando o texto é inserido na caixa de texto Nome).
5- Diferentemente do
List<T>
, o ObservableCollection implementaINotifyCollectionChanged
, que gera eventos quando itens são adicionados, removidos ou quando a coleção muda, o que significa que quando você chamaUsers.Add(newUser)
o ViewModel, o ObservableCollection gera automaticamente o evento CollectionChanged, que o DataGrid escuta, o que significa que novamente o DataGrid é atualizado automaticamente para mostrar o novo item sem exigir nenhum código de atualização manual 🥳.Se usássemos uma lista normal, adicionar itens não atualizaria automaticamente a interface do usuário.
você pode dizer que é muito para um aplicativo simples que tem poucos controles, você está certo, mas o MVVM brilha quando você cria projetos de médio a grande porte.