Your DoSomethingViewModel could have two properties of type FileChooserViewModel that your controls are bound to, then check their string properties for a value.
A simplified version of your FileChooserViewModel could be...
public class FileChooserViewModel : ViewModelBase
{
public const string FilePathPropertyName = "FilePath";
private string _filePath;
public string FilePath
{
get { return _filePath; }
set
{
if (_filePath == value) return;
_filePath = value;
RaisePropertyChanged(FilePathPropertyName);
Messenger.Default.Send(new NotificationMessage("FilePath Updated"));
}
}
}
And your DoSomethingViewModel might look like this...
public class DoSomethingViewModel : ViewModelBase
{
public DoSomethingViewModel()
{
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
public const string FileChooser1PropertyName = "FileChooser1";
private FileChooserViewModel _fileChooser1 = new FileChooserViewModel();
public FileChooserViewModel FileChooser1
{
get { return _fileChooser1; }
set
{
if (_fileChooser1 == value) return;
_fileChooser1 = value;
RaisePropertyChanged(FileChooser1PropertyName);
}
}
public const string FileChooser2PropertyName = "FileChooser2";
private FileChooserViewModel _fileChooser2 = new FileChooserViewModel();
public FileChooserViewModel FileChooser2
{
get { return _fileChooser2; }
set
{
if (_fileChooser2 == value) return;
_fileChooser2 = value;
RaisePropertyChanged(FileChooser2PropertyName);
}
}
public const string BothFilesChosenPropertyName = "BothFilesChosen";
public bool BothFilesChosen
{
get
{
var result = false;
if (FileChooser1 != null && FileChooser2 != null)
result = !string.IsNullOrWhiteSpace(FileChooser1.FilePath)
&& !string.IsNullOrWhiteSpace(FileChooser2.FilePath);
return result;
}
}
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Sender is FileChooserViewModel)
RaisePropertyChanged(BothFilesChosenPropertyName);
}
}
The NotificationMessageReceived method is called with a NotificationMessage is sent from FileChooserViewModel's FilePath property setter, and it in turn raises the property changed event on the BothFilesChosen property.
<UserControl x:Class="DoSomethingProject.Views.DoSomethingView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:DoSomethingProject.Views"
DataContext="{Binding DoSomethingViewModel, Source={StaticResource Locator}}">
<StackPanel>
<views:FileChooser DataContext="{Binding Path=FileChooser1}" />
<views:FileChooser DataContext="{Binding Path=FileChooser2}" />
<Button IsEnabled="{Binding Path=BothFilesChosen}" />
</StackPanel>
</UserControl>
Another way to do this would be to handle the PropertyChanged event on each FileChooserViewModel property, but I prefer using messaging because event handling means you need to make sure you un-handle the events, and this can get messy leading to memory issues when events are missed.