I'm trying to write a ListView
, where for each item there is a button bound to a DelegateCommand
. I want this command's CanExecute
to be based on a boolean property of an item. ItemSource
is an ObservableCollection
and I'm populating it using an async
method. The problem is that when RaiseCanExecuteChanged()
is fired, CanExecute
receives null
as parameter.After that, when I use another UI bound command to RaiseCanExecuteChanged()
, the method behaves properly.
Here's part of the view:
<ListView x:Name="root" ItemsSource="{Binding olVersions}" IsSynchronizedWithCurrentItem="true" HorizontalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=sFullName}" Grid.Column="0" VerticalAlignment="Center"></TextBlock>
<Button Grid.Column="1" Content="Run" CommandParameter="{Binding}" Command="{Binding ElementName=root, Path=DataContext.cRunVersionCommand}"></Button>
<Button Grid.Column="2" Content="Download" CommandParameter="{Binding}" Command="{Binding ElementName=root, Path=DataContext.cDownloadVersionCommand}"></Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here's the ViewModel:
public class VersionsTabViewModel : BindableBase
{
public ObservableCollection<CVersion> olVersions { get; private set; }
public DelegateCommand<CVersion> cRunVersionCommand { get; private set; }
public DelegateCommand<CVersion> cDownloadVersionCommand { get; private set; }
private IVersionManager c_version_manager;
public VersionsTabViewModel(IVersionManager cVersionManager)
{
olVersions = new ObservableCollection<CVersion>();
cRunVersionCommand = new DelegateCommand<CVersion>(v_try_run_version, b_can_run);
cDownloadVersionCommand = new DelegateCommand<CVersion>(v_try_download_version);
c_version_manager = cVersionManager;
v_read_available_versions();
}
private async void v_read_available_versions()
{
List<CVersion> l_versions = await c_version_manager.lGetVersions();
List<CVersion> l_versions_sorted = l_versions.OrderByDescending(cVersion => cVersion.cSemanticVersion).ToList();
olVersions.Clear();
olVersions.AddRange(l_versions_sorted);
cRunVersionCommand.RaiseCanExecuteChanged();
}
private void v_try_run_version(CVersion cVersionToRun)
{
MessageBox.Show($"Run {cVersionToRun.sFullName}", "Run"); //TODO
}
private void v_try_download_version(CVersion cVersionToDownload)
{
MessageBox.Show($"Download {cVersionToDownload.sFullName}", "Download"); //TODO
cRunVersionCommand.RaiseCanExecuteChanged();
}
private bool b_can_run(CVersion cVersion)
{
return cVersion?.bIsInstalled ?? false;
}
}