Search code examples
wpflistviewselecteditemicommand

ICommand overriding SelectedItem


I'm new to WPF. Currently working on a sample app with MVVM pattern. I have a ListView which is populating three columns (Id, Name, Edit). Here, whenever user clicks on Edit button, he would be redirected to "Edit form" with pre-populated values (Selected item in ListView). Edit button is bound to ICommnad and im passing SelectedItem as CommandParameter.

My problem is whenever ICommand fires it contains the previously selected item as SelectedItem.

Any idea how to solve this?

You can find source code at: https://github.com/4pawan/WPF_Sample


Solution

  • The problem is that the button command handler is called before the binding engine has had a chance to update the SelectedItem property.

    First of all you've got some architectural problems. Putting NavigateToForm in ithe EmpFormViewModel is poor SoC and I suspect you've only done it to make the binding easier to declare. It should really be in the parent EmpViewModel and of type RelayCommand<EmpFormViewModel>:

            NavigateToForm = new RelayCommand<EmpFormViewModel>(vm =>
            {
                this.IsImportDataVisible = false;
                this.IsSearchVisible = true;
    
                //do something with vm here
            });
    

    Then all you have to do is modify your button command binding to bind to the parent instead and pass in the list item. So replace all of this...

    <Button Content="Edit" Command="{Binding NavigateToForm}">
        <Button.CommandParameter>
            <MultiBinding Converter="{StaticResource EditEmpConverter }">
                <!--<Binding Path="DataContext" ElementName="mainWindow"/>-->
                <Binding Path="SelectedItem"  ElementName="LstVw"/>
            </MultiBinding>
        </Button.CommandParameter>
    </Button>
    

    ...with this:

    <Button Content="Edit" Command="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=DataContext.NavigateToForm}" CommandParameter="{Binding}" />
    

    Note that I've also removed the converter from the equation, if you really do need a cloned instance then do it in the ViewModel handler where it can at least be more easily tested. Converters are a powerful tool but they're often abused to compensate for poor binding between view model and views. It's the primary responsibility of the view model to present the data in a form that can be easily consumed by the view, if you find yourself relying on them too much or for very simple tasks (such as the case here) then it's often a good indication that the view model isn't doing its job properly.