Home > front end >  Double Click event is not working on ListBox using MVVM in WPF app
Double Click event is not working on ListBox using MVVM in WPF app

Time:08-08

I am facing a problem while binding the double click event on Listbox item. I am using MVVM and Prism. I didn't understand what is wrong here.

View

<ListBox HorizontalAlignment="Center" ItemsSource="{Binding Cities , Source={StaticResource vmC}}" SelectedItem="{Binding SelectedCity , Source={StaticResource vmC}}" Width="100" Height="200">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}">
                        <TextBlock.InputBindings>
                            <MouseBinding Gesture="LeftDoubleClick"                                           
                                  Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.ItemSelectedCommand}"/>
                        </TextBlock.InputBindings>
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

ViewModel

public class CityViewModel : ViewModelBase
    {
       
        public DelegateCommand ItemSelectedCommand { get; private set; }

        public string SelectedCity { get; set; }

        public List<string> Cities { get; private set; }

        public CityViewModel()
        {
            ItemSelectedCommand = new DelegateCommand(OnItemSelected);
            Cities = new List<string>() { "Bangalore", "New York", "Sydney", "London", "Washington" };
        }

        private void OnItemSelected()
        {
            var city = SelectedCity;
        }
    }

CodePudding user response:

MouseBinding is not part of the visual tree. This means, you cannot use Binding.RelativeSource as there is no tree to traverse. Instead you must bind to the current DataContext, which is the item's data model. To accomplish this, you would have tzo introduce a model class e.g. City that exposes a Name and ItemSelectedCommand property.

If moving the command to the item model doesn't make sense in your scenario, you should use a RoutedCommand and handle it e.g., in the parent Window. InputBinding is primarily intended to be used in the view only and therefore encourages the use of RoutedCommand.

In your case, it seems you are only interested in notifying the CityViewModel that the selection has changed. In this case simply call OnItemSelected from the SelectedCity property set():

public class CityViewModel : ViewModelBase
{
  private string selectedCity;
  public string SelectedCity
  {
    get => selectedCity;
    set
    {
      selectedCity = value;
      OnItemSelected();
    }
  }

  public List<string> Cities { get; private set; }

  public CityViewModel()
  {
    ...
  }

  private void OnItemSelected()
  {
    var city = SelectedCity;
  }
}
  • Related