locked
How do I use MVVM to call an asynchronous method in the viewmodel from the view and wait for the resuls in the view? RRS feed

  • Question

  • What I'd like to do is put;

    public async void GetCharacterScores()
            {
                IMobileServiceTable<Character> query = App.MobileService.GetTable<Character>();
                characters = await query.ToEnumerableAsync();

    }

    into the view model and call it from the view. And when the results have been returned call a function in the view:

    public void GetCharacterScores()

    {

    foreach (Character c in characters)
                {
                    Button button = new Button();
                    button.Tag = c.Id;
                    viewModel.characterId = c.Id;
                    button.Content = c.Character_Name;
                    button.Width = 100;
                    button.Height = 100;
                    ButtonsGrid.Children.Add(button);
                    button.Click += button_Click;
                }
     }

    Original code:

    public MainPage() { this.InitializeComponent(); viewModel = new ViewModel(); this.DataContext = viewModel; GetCharacterScores(); } public async void GetCharacterScores() { IMobileServiceTable<Character> query = App.MobileService.GetTable<Character>(); characters = await query.ToEnumerableAsync(); foreach (Character c in characters) { Button button = new Button(); button.Tag = c.Id; viewModel.characterId = c.Id; button.Content = c.Character_Name; button.Width = 100; button.Height = 100; ButtonsGrid.Children.Add(button); button.Click += button_Click; }

    Friday, November 29, 2013 7:53 PM

Answers

  • Hi Bifrost,

    in your ViewModel you should create a Property LoadCommand of type ICommand (resp. DelegateCommand) and a Characters-Property of type ObservableCollection<Character>.

    When the LoadCommand is executed, it fills the Collection. So the code to access your service is now in the ViewModel.

    The foreach-loop in which you're dynamically creating Buttons is - as Buttons are - the visual part and so the View-part.

    So you can continue to do this in C# in your View by adding an event handler to the NotifyCollectionChanged-Event of the ObservableCollection<Character> from your ViewModel. Or you try to go forward with MVVM and push everything to XAML and your ViewModel so that the codebehind is clean.

    To add the Buttons in XAML you could do it like this (not tested, but it should look similar)

    <ItemsControl ItemsSource="{Binding Characters}">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Button Content="{Binding Character_Name}" Command="{Binding Character_Command}"/>
        </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    Now you've still the problem that your Character doesn't have the Character_Command, instead you added this button_Click-Event Handler in Code. Go and create a CharacterViewModel that has that Command and just wraps your Character-object:

    public class CharacterViewModel{

      public CharacterViewModel(Character wrappedObj){...}
      public Character_Name{get{ return wrappedObj.Character_Name}set{...}}
      public ICommand Character_Command{get;private set;}
      ...

    }

    In your main ViewModel change the ObservableCollection<Character> to an ObservableCollection<CharacterViewModel>. After you've loaded the Characters from your service, wrap them in CharacterViewModels and add them to your collection.

    I think that's it, now the coding part needs to be done by you. ;-)




    Thomas Claudius Huber

    "If you can't make your app run faster, make it at least look & feel extremly fast"

    My latest app: The "Womanizer" :-)
    twitter: @thomasclaudiush
    homepage: www.thomasclaudiushuber.com
    author of: ultimate Windows Store Apps handbook | ultimate WPF handbook | ultimate Silverlight handbook

    Friday, November 29, 2013 11:06 PM

All replies

  • Hi Bifrost,

    in your ViewModel you should create a Property LoadCommand of type ICommand (resp. DelegateCommand) and a Characters-Property of type ObservableCollection<Character>.

    When the LoadCommand is executed, it fills the Collection. So the code to access your service is now in the ViewModel.

    The foreach-loop in which you're dynamically creating Buttons is - as Buttons are - the visual part and so the View-part.

    So you can continue to do this in C# in your View by adding an event handler to the NotifyCollectionChanged-Event of the ObservableCollection<Character> from your ViewModel. Or you try to go forward with MVVM and push everything to XAML and your ViewModel so that the codebehind is clean.

    To add the Buttons in XAML you could do it like this (not tested, but it should look similar)

    <ItemsControl ItemsSource="{Binding Characters}">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Button Content="{Binding Character_Name}" Command="{Binding Character_Command}"/>
        </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    Now you've still the problem that your Character doesn't have the Character_Command, instead you added this button_Click-Event Handler in Code. Go and create a CharacterViewModel that has that Command and just wraps your Character-object:

    public class CharacterViewModel{

      public CharacterViewModel(Character wrappedObj){...}
      public Character_Name{get{ return wrappedObj.Character_Name}set{...}}
      public ICommand Character_Command{get;private set;}
      ...

    }

    In your main ViewModel change the ObservableCollection<Character> to an ObservableCollection<CharacterViewModel>. After you've loaded the Characters from your service, wrap them in CharacterViewModels and add them to your collection.

    I think that's it, now the coding part needs to be done by you. ;-)




    Thomas Claudius Huber

    "If you can't make your app run faster, make it at least look & feel extremly fast"

    My latest app: The "Womanizer" :-)
    twitter: @thomasclaudiush
    homepage: www.thomasclaudiushuber.com
    author of: ultimate Windows Store Apps handbook | ultimate WPF handbook | ultimate Silverlight handbook

    Friday, November 29, 2013 11:06 PM
  • Thank you for the excellent advice you gave me Thomas. :)
    Wednesday, December 11, 2013 5:42 PM