MVVM Light - Relaycommand with Pushpins

2019-05-23 20:53发布

问题:

I am data binding some pushpins to a MapLayer. They display fine, but when I use the relaycommand to pass the eventargs from the mouse leftbuttonUp, the object sources is an elipse. I have used this method on a MapPolygon and picked up the information I wanted from the object.

Maybe I am aproaching this badly as I am new to mvvm, so please let me know!

This works for my MapPolygons (vm references the namespace of my extendedMapPolygon class)

    <DataTemplate x:Name="polyTemplate">
        <vm:extendedMapPolygon cName="{Binding _cName}" Locations="{Binding _Locations}" />
    </DataTemplate>

Here is the XAML in the MapLayer

    <m:MapItemsControl ItemTemplate="{StaticResource polyTemplate}" ItemsSource="{Binding  Path=_PolyforDisplay, Mode=TwoWay}"  >
        <i:Interaction.Triggers>
               <i:EventTrigger EventName="MouseLeftButtonUp">
                    <cmd:EventToCommand Command="{Binding Path=PolySelCommand}" PassEventArgsToCommand="True" ></cmd:EventToCommand>
               </i:EventTrigger>
        </i:Interaction.Triggers>
    </m:MapItemsControl>

In my viewModel constructor

PolySelCommand = new RelayCommand<MouseButtonEventArgs>(PolySelCommandExecute);

and finally the actual command

        public RelayCommand<MouseButtonEventArgs> PolySelCommand { get; set; }
    private void PolySelCommandExecute(MouseButtonEventArgs cmp)
    {
        Polygon poly = cmp.OriginalSource as Polygon;
        extendedMapPolygon ePoly = poly.Parent as extendedMapPolygon;
        _MapPolygonSelected =  ePoly.cName;
    }

(I put this here to show both the method I am currently using and in the hope it may be of some use to others!)

When I try the same thing with a Pushpin however, the cmp.OriginalSource is an ellipse and I can not seem to get anything else passed through.

My Pushpin code (I am just using the Pushpins in the MapControl in this code)

    <DataTemplate x:Name="ppTemplate">
        <m:Pushpin ToolTipService.ToolTip="{Binding _psName}" Location="{Binding _Location}" />
    </DataTemplate>

    <m:MapItemsControl ItemTemplate="{StaticResource ppTemplate}" ItemsSource="{Binding Path=_PinsforDisplay, Mode=TwoWay}">
        <i:Interaction.Triggers>
             <i:EventTrigger EventName="MouseLeftButtonUp">
                  <cmd:EventToCommand Command="{Binding Path=pinSelCommand}" PassEventArgsToCommand="True" ></cmd:EventToCommand>
             </i:EventTrigger>
        </i:Interaction.Triggers>
    </m:MapItemsControl>

Should I be using the command parameter? Or someother way of passing text through to my viewmodel when I click on the pushpin, which is what I actually want.

回答1:

I'd move the trigger to the pushpin element.

    <DataTemplate x:Name="ppTemplate">
        <m:Pushpin ToolTipService.ToolTip="{Binding _psName}" Location="{Binding _Location}">
             <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseEnter">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseLeftButtonUp">
                                <cmd:EventToCommand Command="{Binding Path=DataContext.pinSelCommand}" 
                                                    CommandParameter="{Binding WhateverPropertyHasTheText" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
        </m:Pushpin>
    </DataTemplate>

Notice I'm passing as a command parameter whatever property you want to send from the objects in _PinsForDisplay. Also, the binding for the command changed slightly, as the binding is different from inside a datatemplate.

And then you'd have to change your RelayCommand on the viewmodel to RelayCommand.

I didn't test this code, but something very similar is working for me so hopefully it can lead you toward a solution.