/ / Używam EF, Prism, Wpf i mam problem z RaiseCanExecute (), a także potrzebuję pomocy, co zrobić z czystymi klasami POCO - wpf, entity-framework, mvvm, prism, poco

Używam EF, Prism, Wpf i mam problem z RaiseCanExecute (), a także potrzebuję pomocy, co zrobić z czystymi klasami POCO - wpf, entity-framework, mvvm, prism, poco

Buduję aplikację w Wpf z EF i Prism. Dotarłem do momentu, w którym jestem zdezorientowany co do personelu, pozwól mi wyjaśnić. Zwróć uwagę, że jest to bardzo uproszczona wersja. Mam moje klasy POCO, które wyglądają tak

public class SaleText
{
public int SaleTextId { get; set; }
public int SaleDepartmentId { get; set; }
public string Description { get; set; }

public SaleDepartment SaleDepartment { get; set; }
}

Teraz mój ViewModel wygląda następująco:

public class SaleTextViewModel
{
private SaleText selectedSaleText;
public SaleText SelectedSaleText
{
get { return selectedSaleText; }
set
{
selectedSaleText = value;
OnPropertyChanged();
}
}

Teraz mój xaml wygląda tak

    <Label Content="Information" />
<TextBox Width="200"
Height="100"
AcceptsReturn="True"
Text="{Binding SelectedSaleText.Description }"
TextWrapping="Wrap" />
<Button Command="{Binding SaveCommand}" Content="Save" />

Przycisk zapisu jest aktywny tylko po wpisaniu opisu.

 private bool CanSave()
{
if (SelectedEntity.Description)
{
return true;
}
else
{
return false;
}
}

A teraz zaczynają się problemy Nigdy nie otrzymuję powiadomieniagdy opis zostanie zmieniony, ponieważ ta właściwość nie ma zmienionej właściwości Wł. Tak więc pomyślałem, po prostu rozszerzam go do w pełni zaimplementowanej właściwości, takiej jak ta.

    private string description;
public string Description
{
get { return description; }
set
{
description = value;
OnPropertyChanged();
}
}

Wygląda świetnie, a seter nazywa się za każdym razem, gdy coś się zmieniło. Ale prawdziwe trudności zaczynają się tutaj, używam tego polecenia delegowania pryzmatu 5

    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);

}

Ale przycisk nigdy się nie aktualizuje, że można go teraz zapisać, ponieważ oczywiście tego potrzebuje

     SaveCommand.RaiseCanExecuteChanged(); inside here  where the space is.

private string description;
public string Description
{
get { return description; }
set
{
description = value;

OnPropertyChanged();
}
}

Ale nie mogę tego zrobić, ponieważ jednostki znajdują się w innym projekcie, a mój projekt wpf odwołuje się do projektu elementów, a nie odwrotnie.

Czy ktoś może mi powiedzieć, co mam zrobić w tej sytuacji?? Czy zostawiam moje POCO tak, jak było na początku, z własnymi właściwościami, a następnie tworzę kolejny zestaw podmiotów, które następnie zajmą się INPC RaiseCanExecute, Validations etc? jeśli tak, w jaki sposób mogę przetłumaczyć te dwa?

Masz jakieś pomysły?

EDYTOWAĆ: Oto możliwe rozwiązanie

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,
};
}

Oto zmiana 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);
}
}

A POCO wcale nie jest modyfikowany. Jeśli ktoś ma inne lub lepsze rozwiązanie, podziel się nim ze mną :)

Odpowiedzi:

1 dla odpowiedzi № 1
   protected FormViewModelBase(IRegionManager regionManager)
: base(regionManager)
{
SaveCommand = new DelegateCommand(Save, CanSave);
PropertyChanged += (sender, args) => {
if(sender == SelectedSaleText &&
args.PropertyName == "Description")
SaveCommand.RaiseCanExecuteChanged();
};
}

Zawsze możesz słuchać zmian właściwości w SelectedSaleText.