简体   繁体   中英

How can Parent class method subscribe to the child class Event?

In WPF (C#) application, my target is to execute a delete command from the child view. The Delete command will delete the Object itself from the Parent collection. Here is the Data template of the child ( from .xaml file )

<DataTemplate DataType="{x:Type dataModel:AppLeg}">
  <Menu Grid.Column="2">
   <MenuItem Header="Delete Leg" Command="{Binding DeleteLegCommand}" 
     CommandParameter="{Binding}"/> 
  </Menu>
 </DataTemplate>

 <DataTemplate DataType="{x:Type dataModel:DestinationSchedule}">        
        <ItemsControl dd:DragDrop.IsDragSource="True"
                      dd:DragDrop.IsDropTarget="True"
                      dd:DragDrop.DropHandler="{Binding}"
                      Focusable="False"
                      ItemsSource="{Binding AppLegs}"
                      SnapsToDevicePixels="True"
                       FontWeight="SemiBold"
                      UseLayoutRounding="True">               
        </ItemsControl>            
    </DataTemplate>

In the DataModel, The Command_DeleteTripLeg method is being executed that means, the Event EventDeleteLeg is being invoked also.

   public class AppLeg
    {
   public event Action<AppLeg> EventDeleteLeg;
   public RelayCommand<object> DeleteTripLegCommand => new 
        RelayCommand<object>(Command_DeleteLeg, true);

    private void Command_DeleteTripLeg(object leg )
    {
        EventDeleteLeg?.Invoke((AppLeg)Leg);
    }

Now, In the parent class ( Collection class of the AppLeg class ) I have the collection object of the Appleg class.

public class DestinationSchedule : ViewModelBase
{
    #region Fields

    private ObservableCollection<AppLeg> _appLegs;

    private void deleteAppLegFromCollection( AppLeg appLeg)
    {
       _appLegs.Remove( appLeg )
    }
}

So My target is to subscribe deleteAppLegFromCollection() method of the parent DestinationSchedule model class to the EventDeleteLeg event so that, On Execution of the "DeleteLegCommand" command the AppLeg object can be removed from the collection _tripLegs.

AppDestination.cs class

public class AppDestination : ViewModelBase
  {
    private ObservableCollection<DestinationSchedule> _destinationSchedule;

    public ObservableCollection<DestinationSchedule> DestinationSchedule
    {
        get => _destinationSchedule;
        set => Set(ref _destinationSchedule, value);
    }
}

ScheduleDestinationsView.xaml code

<d:UserControl.DataContext>
    <viewModel:ScheduleDestinationsViewModel/>
</d:UserControl.DataContext>
<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>                
            <ResourceDictionary 
            Source="pack://application:,,,/SharedResources;
                                component/DataTemplates.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

  <Grid SnapsToDevicePixels="True" UseLayoutRounding="True">
    <ListBox VerticalAlignment="Stretch"
                  VerticalContentAlignment="Stretch"
                  Focusable="False"
                  ItemsSource="{Binding AppDestinations}">
        <ItemsControl.Template>
            <ControlTemplate>
                <ItemsPresenter/>
            </ControlTemplate>
        </ItemsControl.Template>
        </ListBox>
         </Grid>

And ScheduleDestinationsViewModel.cs class

public class ScheduleDestinationsViewModel : ViewModelBase
{       
    private ObservableCollection<AppDestination> _appDestinations;
    public ObservableCollection<AppDestination> AppDestinations
    {
        get => _appDestinations;
        set => Set(ref _appDestinations, value);
    }

    public ScheduleDestinationsViewModel()
    {
        AppDestinations = new ObservableCollection<AppDestination>();
    }
}

How can Parent class subscribe to the child class Event? Please advise. An alternative approach is also well come. Thanks.

Move the delete command to the parent class ( DestinationSchedule ) where the AppLegs source collection is defined and invoke the command of this one.

You can bind to a command of a parent element by specifying a RelativeSource :

<Menu Grid.Column="2">
    <MenuItem Header="Delete Leg" Command="{Binding DataContext.DeleteLegCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
              CommandParameter="{Binding}"/>
</Menu>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM