Reputation: 6037
I am using MVVM Light in a (pretty simple) WPF project.
I have a list of versions, and for each of them there is a button "activate" and "archive". Only one version can be active.
When clicking on "activate", the software must archive the currently active version, and activate the selected one.
How would you modelize this ? I'm currently using a pretty ugly solution : the selected version re-instantiates the "active version" and archives it, so obviously the previously-active version isn't "refreshed".
The main window contains a list of versions, displayed in a ListBox (see this question).
public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel()
{
this.InstalledVersions = InstalledVersionViewModel.GetInstalledVersions();
}
public ObservableCollection<InstalledVersionViewModel> InstalledVersions { get; set; }
}
The InstalledVersionViewModel is (simplified) like this :
public class InstalledVersionViewModel : ViewModelBase
{
public InstalledVersionViewModel()
{
this.HandleActivateVersionCommand = new RelayCommand<RoutedEventArgs>(e => { this.ActivateVersion(); });
this.HandleArchiveVersionCommand = new RelayCommand<RoutedEventArgs>(e => { this.ArchiveVersion(); });
}
public string FolderPath { get; set; }
public RelayCommand<RoutedEventArgs> HandleActivateVersionCommand { get; private set; }
public RelayCommand<RoutedEventArgs> HandleArchiveVersionCommand { get; private set; }
public string VersionNumber { get; set; }
public static InstalledVersionViewModel GetCurrentVersion()
{
return GetVersionInfos(baseInstallPath); // returns the currently-active version
}
public static ObservableCollection<InstalledVersionViewModel> GetInstalledVersions()
{
var list = new ObservableCollection<InstalledVersionViewModel>();
// snip : fill the list from detected versions
return list;
}
private void ActivateVersion()
{
// snip
GetCurrentVersion().Archive();
// snip
}
private void ArchiveVersion()
{
// snip
}
}
The problem is in the ActivateVersion() method : I'm getting a new version instance to archive it, so obviously the version instance in the list is never aware of this change. But I don't know how to change the behavior to archive the version in the list instead. I'm pretty sure there should be either some kind of messaging system, a wrapper or an overarching structure, but I can't quite put my finger on it.
Thanks !
Upvotes: 1
Views: 79
Reputation: 39007
To me, it should be handled in the MainViewModel
. For instance, add a property IsActive
to your InstalledVersionViewModel
, and subscribe to the PropertyChanged
event from your MainViewModel
. When the event is raised, browse your InstalledVersions
list to find the previously active item, and call the Archive
method on it.
To subscribe to the event, simply browse your list after creating it:
public MainWindowViewModel()
{
this.InstalledVersions = InstalledVersionViewModel.GetInstalledVersions();
foreach (var version in this.InstalledVersions)
{
version.PropertyChanged += this.VersionPropertyChanged;
}
}
Then, in the event, check which property has been changed:
private void VersionPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsActive")
{
var changedVersion = (Version)sender;
// Checks that the version has been activated
if (changedVersion.IsActive)
{
// Finds the previously active version and archive it
foreach (var version in this.InstalledVersions)
{
if (version.IsActive && version != changedVersion)
{
version.Archive();
}
}
}
}
}
Upvotes: 1