Eu estou construindo um aplicativo em Wpf com EF e Prism. Cheguei a um ponto em que estou confuso sobre a equipe, deixe-me explicar. Por favor, note que esta é uma versão muito simplificada. Eu tenho minhas aulas POCO que se parecem com isso
public class SaleText
{
public int SaleTextId { get; set; }
public int SaleDepartmentId { get; set; }
public string Description { get; set; }
public SaleDepartment SaleDepartment { get; set; }
}
Agora meu ViewModel é assim:
public class SaleTextViewModel
{
private SaleText selectedSaleText;
public SaleText SelectedSaleText
{
get { return selectedSaleText; }
set
{
selectedSaleText = value;
OnPropertyChanged();
}
}
Agora meu xaml se parece com isso
<Label Content="Information" />
<TextBox Width="200"
Height="100"
AcceptsReturn="True"
Text="{Binding SelectedSaleText.Description }"
TextWrapping="Wrap" />
<Button Command="{Binding SaveCommand}" Content="Save" />
O botão salvar é ativado apenas quando a descrição foi digitada.
private bool CanSave()
{
if (SelectedEntity.Description)
{
return true;
}
else
{
return false;
}
}
E agora os problemas começam eu nunca sou notificadoquando a descrição é alterada porque essa propriedade não tem a propriedade On alterada. Então eu pensei, eu só expandi-lo para a propriedade totalmente implementada como esta.
private string description;
public string Description
{
get { return description; }
set
{
description = value;
OnPropertyChanged();
}
}
Parece ótimo e o levantador é chamado toda vez que algo mudou. Mas as dificuldades reais começam aqui, eu estou usando o comando delegado prisma 5 como este
public DelegateCommand SaveCommand { get; set; }
protected FormViewModelBase(IRegionManager regionManager)
: base(regionManager)
{
SaveCommand = new DelegateCommand(Save, CanSave);
}
protected override bool CanSave()
{
if (SelectedEntity.Description)
{
return true;
}
else
{
return false;
}
}
protected override void Save()
{
// then other code deals with saving changes
EventAggregator.GetEvent<UpdateSaleDepartmentSaleTextEvent>()
.Publish(SelectedEntity);
}
Mas o botão nunca é atualizado, é ok salvar agora, porque obviamente precisa disso
SaveCommand.RaiseCanExecuteChanged(); inside here where the space is.
private string description;
public string Description
{
get { return description; }
set
{
description = value;
OnPropertyChanged();
}
}
Mas eu não posso fazê-lo, porque as entidades estão em um projeto diferente, e meu projeto wpf está fazendo referência ao projeto de entidades e não o contrário.
Alguém pode me dizer o que eu faço nesta situação? Eu deixo meu POCO como estava no começo com apenas propriedades, e então crio outro conjunto de entidades, que então lidam com INPC RaiseCanExecute, Validações etc? se sim, como faço para traduzir entre os dois?
Alguma idéia por favor?
EDITAR: Aqui está uma solução possível
public class FooSaleText : INotifyPropertyChanged
{
public int SaleTextId { get; set; }
public int SaleDepartmentId { get; set; }
readonly DelegateCommand command;
public FooSaleText(DelegateCommand command)
{
this.command = command;
}
private string description;
public string Description
{
get { return description; }
set
{
description = value;
command.RaiseCanExecuteChanged();
OnPropertyChanged();
}
}
private string importText;
public string ImportText
{
get { return importText; }
set
{
importText = value;
command.RaiseCanExecuteChanged();
OnPropertyChanged();
}
}
public SaleDepartment SaleDepartment { get; set; }
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class SaleTextConversion
{
readonly DelegateCommand command;
public SaleTextConversion(DelegateCommand command)
{
this.command = command;
}
public FooSaleText Convert(SaleText saleText)
{
return new FooSaleText(command)
{
SaleTextId = saleText.SaleTextId,
SaleDepartmentId = saleText.SaleDepartmentId,
SaleDepartment = saleText.SaleDepartment,
Description = saleText.Description,
};
}
public SaleText ConvertBack(FooSaleText saleText)
{
return new SaleText()
{
SaleTextId = saleText.SaleTextId,
SaleDepartmentId = saleText.SaleDepartmentId,
SaleDepartment = saleText.SaleDepartment,
Description = saleText.Description,
};
}
Aqui está a mudança do viemodel
public class SaleTextViewModel
{
private FooSaleText selectedSaleText;
public FooSaleText SelectedSaleText
{
get { return selectedSaleText; }
set
{
selectedSaleText = value;
OnPropertyChanged();
}
public void TestMethod()
{
using (var unitOfWork = new UnitOfWorkMAOption())
{
var foo = new SaleTextConversion(SaveCommand);
SelectedSaleText =
foo.Convert(unitOfWork.SaleTextRepository.Find(Id);
}
}
E o POCO não é modificado de forma alguma. Se alguém tiver uma solução diferente ou melhor, por favor, compartilhe comigo :)
Respostas:
1 para resposta № 1 protected FormViewModelBase(IRegionManager regionManager)
: base(regionManager)
{
SaveCommand = new DelegateCommand(Save, CanSave);
PropertyChanged += (sender, args) => {
if(sender == SelectedSaleText &&
args.PropertyName == "Description")
SaveCommand.RaiseCanExecuteChanged();
};
}
Você sempre pode ouvir as alterações da propriedade em SelectedSaleText
.