4
Following MVVM model, I am not able to update the values of a variable of an object in a collection, show them on the screen or the user type and this value be passed to the variable.
In my case, I have a customer registration screen and this client may contain more than one address. Well, a control of the type ItemsControl
receives in attribute ItemsSource
the Binding
of the collection Endereços
and in the attribute DataTemplate
the layout of each ItemControl(endereço)
and each field with its respective Binding
.
Follow the codes for better understanding:
Viewmodel
public class ClienteViewModel : INotifyPropertyChanged
{
public ClienteViewModel()
{
Enderecos = new ObservableCollection<EnderecoViewModel>();
}
private ObservableCollection<EnderecoViewModel> _enderecos;
public ObservableCollection<EnderecoViewModel> Enderecos
{
get { return _enderecos; }
set
{
_enderecos = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
XAML
<ItemsControl ItemsSource="{Binding Path=Enderecos, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type endereco:EnderecoViewModel}">
<TextBlock Text="CEP:"/>
<xctk:MaskedTextBox Mask="00000-000" TextChanged="TbCep_OnTextChanged" Text="{Binding Cep}" Tag="{Binding EnderecoId}"/>
<TextBlock Text="Logradouro"/>
<TextBox Text="{Binding Logradouro}"/>
<TextBlock Text="Número:" />
<TextBox Text="{Binding Numero}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
XAML.Cs
private void TbCep_OnTextChanged(object sender, TextChangedEventArgs e)
{
var enderecoOnList =
_clienteViewModel.Enderecos.FirstOrDefault(
x =>
x.EnderecoId == Guid.Parse(sender.GetType().GetProperty("Tag").GetValue(sender).ToString()));
var endereco = new Endereco();
if (enderecoOnList != null && enderecoOnList.Cep != null)
{
var cep = enderecoOnList.Cep.Replace("-", "");
if (cep.Length == 8)
{
endereco = BuscarEnderecoPorCep(cep);
if (endereco != null)
{
enderecoOnList.Logradouro = endereco.Logradouro;
enderecoOnList.Complemento = endereco.Complemento;
enderecoOnList.Bairro = endereco.Bairro;
enderecoOnList.Cidade = endereco.Cidade;
enderecoOnList.Estado = endereco.Estado;
enderecoOnList.CodigoIbge = endereco.CodigoIbge;
enderecoOnList.Pais = "Brasil";
}
}
}
}
When this event "TbCep_OnTextChanged"
is triggered, the variable enderecoOnList
receives the address of the right position, but all variables are set as null
, including the zip code entered by the user on the screen.
When I change any variable of an address object via screen, the Addresses collection does not receive this value at that position or at another collection position.
NOTE: I have an add button, which adds a new address object to the Addresses collection and occurs Binding normally on the screen. I also have a remove button, which removes an address object from the Addresses collection, which also works perfectly. That is, the Binding connected to Addresses works, but the Binding linked to a variable of a collection address object does not work.
How can I solve this problem, I have tried to set the Binding Mode as Twoway, but I have not yet succeeded, or what to fix in my code?