I am using MVVM Light in a Windows Phone 7 (7.1 using the wp8 SDK and VS Ultimate 2012) application that asynchroneously retrieves data from a web service application. I use RelayCommands on each page that execute async methods to get the data then navigate to the next page. For example, in one of my ViewModels, I declare the following ICommand :
public ICommand ShowTreatmentDetailsCommand { get; set; }
then, in the VM's constructor, I assign it this way :
ShowTreatmentDetailsCommand = new RelayCommand(ShowTreatmentDetails);
and here's the method called by that command :
private async void ShowTreatmentDetails()
{
try
{
Treatment refreshedTreatment = await treatmentService.LoadSingle(SelectedTreatment.id, LoggedUser.logon, LoggedUser.pwHash);
if (refreshedTreatment != null)
{
DrugGroup anaestGroup = null;
DrugGroup surgGroup = null;
IEnumerable<DrugGroup> groups = await drugGroupService.Load(
refreshedTreatment.id,
LoggedUser.logon,
LoggedUser.pwHash);
anaestGroup = groups
.Where(g => g.type == DrugType.Anaesthetic)
.SingleOrDefault<DrugGroup>();
surgGroup = groups
.Where(g => g.type == DrugType.Surgical)
.SingleOrDefault<DrugGroup>();
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add(Keys.AnaestDrugGroup, anaestGroup);
parameters.Add(Keys.SurgDrugGroup, surgGroup);
parameters.Add(Keys.SelectedTreatment, refreshedTreatment);
Messenger.Default.Send(parameters);
}
else
{
// Display error message
}
RefreshData();
}
catch (NullReferenceException) { }
}
This command is called from the View's xaml code when an item is selected from a ListBox, using an EventTrigger and the EventToCommand class (but the problem stays the same with button-related commands. Just in case, here's my ListBox element :
<ListBox x:Name="lbxTreatmentList"
ItemsSource="{Binding Treatments}"
SelectedItem="{Binding SelectedTreatment, Mode=TwoWay}">
<int:Interaction.Triggers>
<int:EventTrigger EventName="SelectionChanged">
<com:EventToCommand Command="{Binding ShowTreatmentDetailsCommand}"
PassEventArgsToCommand="True" />
</int:EventTrigger>
</int:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<custom:TreatmentListItem PatientName="{Binding patient}"
OpeDescription="{Binding description}"
StartedAt="{Binding startedAt}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And another exaple with a button :
<Button Grid.Row="2"
HorizontalAlignment="Center"
Foreground="{StaticResource BeldicoBlue}"
BorderBrush="{StaticResource BeldicoBlue}"
Margin="0,12,0,0"
Padding="24,12"
Command="{Binding ValidateCommand}">
<TextBlock Text="Validate this treatment" FontWeight="ExtraBold" />
</Button>
The problem is that, each time the command is fired, the related method gets executed an increasing number of times. I.e. : once at the first call, then twice, then three, four, five... times. Which quickly becomes bandwidth and time consuming, as there is an async service call in the method.
I definitely don't get the reason behind this behavior, can anyone help ?
public ICommand ShowTreatmentDetailsCommand
and thenShowTreatmentDetailsCommand = new RelayCommand
. Replace ICommand with RelayCommand. Probably won't fix your problem, but I don't if I get this right. You click on the button, method will be called ONCE. You click on the button again, the method will be called TWICE, is that correct? – Rudi