MVVM Databinding, Commands, Async - MVVM.Light












0












$begingroup$


I'm new to C#, WPF and MVVM and I don't want to make common mistakes right from the beginning and get used to them.

Already read some similar questions on best practices for WPF/MVVM but none of them included async/await patterns.



I'm also using MahApps.Metro for UI and MVVM.Light Toolkit.



Any advise or guidance would be greatly appreciated!



MainWindow.xaml (cropped)






[...]
<Grid>
<TabControl Controls:TabControlHelper.Underlined="TabPanel">
<TabItem Header="Programs">
<Grid DataContext="{Binding ProgramsViewModelMain, Source= {StaticResource Locator}}">
<Button Content="Refresh" Command="{Binding LoadDataBase}" Height="10" Width="100" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<Controls:ProgressRing IsActive="{Binding IsLoading}" DockPanel.Dock="Top" Height="60" Width="60" Margin="0 10 0 0"/>
<DataGrid Margin="0 25 0 0" EnableRowVirtualization="True" GridLinesVisibility="All" Grid.ColumnSpan="2" ItemsSource="{Binding OfsItems}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ProductionOrder}" Header="Production Order"/>
<DataGridTextColumn Binding="{Binding OfsTask}" Header="Task"/>
</DataGrid.Columns>
<DataGrid.Style>
<Style TargetType="DataGrid" BasedOn="{StaticResource MetroDataGrid}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoading}" Value="False">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Style>
</DataGrid>
</Grid>
</TabItem>
[...]





Model



using GalaSoft.MvvmLight;
using System.Data.Odbc;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace CPM_WPF.Model
{
public class Ofs : ObservableObject
{
public async Task<ObservableCollection<OfsItem>> GetOfsItemsAsync()
{
ObservableCollection<OfsItem> ofsdata = new ObservableCollection<OfsItem>();
List<OfsItem> ofslist = new List<OfsItem>();

ofslist = await Task.Run(() => DonwloadOfsData()); //get items from database

foreach (var item in ofslist) //list to observablecollection
{
ofsdata.Add(item);
}
return ofsdata;
}

private List<OfsItem> DonwloadOfsData()
{
List<OfsItem> ofslist = new List<OfsItem>();

OdbcConnection cn;
OdbcCommand cmd;
OdbcDataReader dr;

//connect to database
string query;
query = "Select * from tblProductionOrders WHERE Task = 2830";
cn = new OdbcConnection("Driver={SQL Server};Server=LUDUDSVPSQL1201;Database=OFS460;");
cmd = new OdbcCommand(query, cn);
cn.Open();

dr = cmd.ExecuteReader();

//read values
while (dr.Read())
{
ofslist.Add(new OfsItem //add items to list
{
ProductionOrder = dr.GetInt32(1),
OfsTask = dr.GetInt32(6)
});
};
return ofslist;
}

}
public class OfsItem : ObservableObject
{
private int po;
private int ofsTask;
public int ProductionOrder
{
get => po;
set => Set<int>(() => this.ProductionOrder, ref po, value);
}
public int OfsTask
{
get => ofsTask;
set => Set<int>(() => this.OfsTask, ref ofsTask, value);
}
}
}


ViewModel



using CPM_WPF.Model;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;

namespace CPM_WPF.ViewModel
{
public class ProgramsViewModel : ViewModelBase
{
public ICommand LoadDataBase { get; private set; }
public ProgramsViewModel()
{
LoadDataBase = new RelayCommand(async () => await LoadDataBaseMethod());
}

public async Task LoadDataBaseMethod()
{
IsLoading = true;
Ofs ofs = new Ofs();
OfsItems = await Task.Run(() => ofs.GetOfsItemsAsync());
IsLoading = false;
}

private ObservableCollection<OfsItem> ofsItems;
private bool isLoading;

public bool IsLoading
{
get => isLoading;
set => Set<bool>(() => this.IsLoading, ref isLoading, value);
}

public ObservableCollection<OfsItem> OfsItems
{
get => ofsItems;
set => Set<ObservableCollection<OfsItem>>(() => this.OfsItems, ref ofsItems, value);
}
}
}









share|improve this question









$endgroup$

















    0












    $begingroup$


    I'm new to C#, WPF and MVVM and I don't want to make common mistakes right from the beginning and get used to them.

    Already read some similar questions on best practices for WPF/MVVM but none of them included async/await patterns.



    I'm also using MahApps.Metro for UI and MVVM.Light Toolkit.



    Any advise or guidance would be greatly appreciated!



    MainWindow.xaml (cropped)






    [...]
    <Grid>
    <TabControl Controls:TabControlHelper.Underlined="TabPanel">
    <TabItem Header="Programs">
    <Grid DataContext="{Binding ProgramsViewModelMain, Source= {StaticResource Locator}}">
    <Button Content="Refresh" Command="{Binding LoadDataBase}" Height="10" Width="100" VerticalAlignment="Top" HorizontalAlignment="Right"/>
    <Controls:ProgressRing IsActive="{Binding IsLoading}" DockPanel.Dock="Top" Height="60" Width="60" Margin="0 10 0 0"/>
    <DataGrid Margin="0 25 0 0" EnableRowVirtualization="True" GridLinesVisibility="All" Grid.ColumnSpan="2" ItemsSource="{Binding OfsItems}" AutoGenerateColumns="False">
    <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding ProductionOrder}" Header="Production Order"/>
    <DataGridTextColumn Binding="{Binding OfsTask}" Header="Task"/>
    </DataGrid.Columns>
    <DataGrid.Style>
    <Style TargetType="DataGrid" BasedOn="{StaticResource MetroDataGrid}">
    <Setter Property="Visibility" Value="Hidden"/>
    <Style.Triggers>
    <DataTrigger Binding="{Binding IsLoading}" Value="False">
    <Setter Property="Visibility" Value="Visible"/>
    </DataTrigger>
    </Style.Triggers>
    </Style>
    </DataGrid.Style>
    </DataGrid>
    </Grid>
    </TabItem>
    [...]





    Model



    using GalaSoft.MvvmLight;
    using System.Data.Odbc;
    using System.Collections.ObjectModel;
    using System.Threading.Tasks;
    using System.Collections.Generic;

    namespace CPM_WPF.Model
    {
    public class Ofs : ObservableObject
    {
    public async Task<ObservableCollection<OfsItem>> GetOfsItemsAsync()
    {
    ObservableCollection<OfsItem> ofsdata = new ObservableCollection<OfsItem>();
    List<OfsItem> ofslist = new List<OfsItem>();

    ofslist = await Task.Run(() => DonwloadOfsData()); //get items from database

    foreach (var item in ofslist) //list to observablecollection
    {
    ofsdata.Add(item);
    }
    return ofsdata;
    }

    private List<OfsItem> DonwloadOfsData()
    {
    List<OfsItem> ofslist = new List<OfsItem>();

    OdbcConnection cn;
    OdbcCommand cmd;
    OdbcDataReader dr;

    //connect to database
    string query;
    query = "Select * from tblProductionOrders WHERE Task = 2830";
    cn = new OdbcConnection("Driver={SQL Server};Server=LUDUDSVPSQL1201;Database=OFS460;");
    cmd = new OdbcCommand(query, cn);
    cn.Open();

    dr = cmd.ExecuteReader();

    //read values
    while (dr.Read())
    {
    ofslist.Add(new OfsItem //add items to list
    {
    ProductionOrder = dr.GetInt32(1),
    OfsTask = dr.GetInt32(6)
    });
    };
    return ofslist;
    }

    }
    public class OfsItem : ObservableObject
    {
    private int po;
    private int ofsTask;
    public int ProductionOrder
    {
    get => po;
    set => Set<int>(() => this.ProductionOrder, ref po, value);
    }
    public int OfsTask
    {
    get => ofsTask;
    set => Set<int>(() => this.OfsTask, ref ofsTask, value);
    }
    }
    }


    ViewModel



    using CPM_WPF.Model;
    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Command;
    using System.Collections.ObjectModel;
    using System.Threading.Tasks;
    using System.Windows.Input;

    namespace CPM_WPF.ViewModel
    {
    public class ProgramsViewModel : ViewModelBase
    {
    public ICommand LoadDataBase { get; private set; }
    public ProgramsViewModel()
    {
    LoadDataBase = new RelayCommand(async () => await LoadDataBaseMethod());
    }

    public async Task LoadDataBaseMethod()
    {
    IsLoading = true;
    Ofs ofs = new Ofs();
    OfsItems = await Task.Run(() => ofs.GetOfsItemsAsync());
    IsLoading = false;
    }

    private ObservableCollection<OfsItem> ofsItems;
    private bool isLoading;

    public bool IsLoading
    {
    get => isLoading;
    set => Set<bool>(() => this.IsLoading, ref isLoading, value);
    }

    public ObservableCollection<OfsItem> OfsItems
    {
    get => ofsItems;
    set => Set<ObservableCollection<OfsItem>>(() => this.OfsItems, ref ofsItems, value);
    }
    }
    }









    share|improve this question









    $endgroup$















      0












      0








      0





      $begingroup$


      I'm new to C#, WPF and MVVM and I don't want to make common mistakes right from the beginning and get used to them.

      Already read some similar questions on best practices for WPF/MVVM but none of them included async/await patterns.



      I'm also using MahApps.Metro for UI and MVVM.Light Toolkit.



      Any advise or guidance would be greatly appreciated!



      MainWindow.xaml (cropped)






      [...]
      <Grid>
      <TabControl Controls:TabControlHelper.Underlined="TabPanel">
      <TabItem Header="Programs">
      <Grid DataContext="{Binding ProgramsViewModelMain, Source= {StaticResource Locator}}">
      <Button Content="Refresh" Command="{Binding LoadDataBase}" Height="10" Width="100" VerticalAlignment="Top" HorizontalAlignment="Right"/>
      <Controls:ProgressRing IsActive="{Binding IsLoading}" DockPanel.Dock="Top" Height="60" Width="60" Margin="0 10 0 0"/>
      <DataGrid Margin="0 25 0 0" EnableRowVirtualization="True" GridLinesVisibility="All" Grid.ColumnSpan="2" ItemsSource="{Binding OfsItems}" AutoGenerateColumns="False">
      <DataGrid.Columns>
      <DataGridTextColumn Binding="{Binding ProductionOrder}" Header="Production Order"/>
      <DataGridTextColumn Binding="{Binding OfsTask}" Header="Task"/>
      </DataGrid.Columns>
      <DataGrid.Style>
      <Style TargetType="DataGrid" BasedOn="{StaticResource MetroDataGrid}">
      <Setter Property="Visibility" Value="Hidden"/>
      <Style.Triggers>
      <DataTrigger Binding="{Binding IsLoading}" Value="False">
      <Setter Property="Visibility" Value="Visible"/>
      </DataTrigger>
      </Style.Triggers>
      </Style>
      </DataGrid.Style>
      </DataGrid>
      </Grid>
      </TabItem>
      [...]





      Model



      using GalaSoft.MvvmLight;
      using System.Data.Odbc;
      using System.Collections.ObjectModel;
      using System.Threading.Tasks;
      using System.Collections.Generic;

      namespace CPM_WPF.Model
      {
      public class Ofs : ObservableObject
      {
      public async Task<ObservableCollection<OfsItem>> GetOfsItemsAsync()
      {
      ObservableCollection<OfsItem> ofsdata = new ObservableCollection<OfsItem>();
      List<OfsItem> ofslist = new List<OfsItem>();

      ofslist = await Task.Run(() => DonwloadOfsData()); //get items from database

      foreach (var item in ofslist) //list to observablecollection
      {
      ofsdata.Add(item);
      }
      return ofsdata;
      }

      private List<OfsItem> DonwloadOfsData()
      {
      List<OfsItem> ofslist = new List<OfsItem>();

      OdbcConnection cn;
      OdbcCommand cmd;
      OdbcDataReader dr;

      //connect to database
      string query;
      query = "Select * from tblProductionOrders WHERE Task = 2830";
      cn = new OdbcConnection("Driver={SQL Server};Server=LUDUDSVPSQL1201;Database=OFS460;");
      cmd = new OdbcCommand(query, cn);
      cn.Open();

      dr = cmd.ExecuteReader();

      //read values
      while (dr.Read())
      {
      ofslist.Add(new OfsItem //add items to list
      {
      ProductionOrder = dr.GetInt32(1),
      OfsTask = dr.GetInt32(6)
      });
      };
      return ofslist;
      }

      }
      public class OfsItem : ObservableObject
      {
      private int po;
      private int ofsTask;
      public int ProductionOrder
      {
      get => po;
      set => Set<int>(() => this.ProductionOrder, ref po, value);
      }
      public int OfsTask
      {
      get => ofsTask;
      set => Set<int>(() => this.OfsTask, ref ofsTask, value);
      }
      }
      }


      ViewModel



      using CPM_WPF.Model;
      using GalaSoft.MvvmLight;
      using GalaSoft.MvvmLight.Command;
      using System.Collections.ObjectModel;
      using System.Threading.Tasks;
      using System.Windows.Input;

      namespace CPM_WPF.ViewModel
      {
      public class ProgramsViewModel : ViewModelBase
      {
      public ICommand LoadDataBase { get; private set; }
      public ProgramsViewModel()
      {
      LoadDataBase = new RelayCommand(async () => await LoadDataBaseMethod());
      }

      public async Task LoadDataBaseMethod()
      {
      IsLoading = true;
      Ofs ofs = new Ofs();
      OfsItems = await Task.Run(() => ofs.GetOfsItemsAsync());
      IsLoading = false;
      }

      private ObservableCollection<OfsItem> ofsItems;
      private bool isLoading;

      public bool IsLoading
      {
      get => isLoading;
      set => Set<bool>(() => this.IsLoading, ref isLoading, value);
      }

      public ObservableCollection<OfsItem> OfsItems
      {
      get => ofsItems;
      set => Set<ObservableCollection<OfsItem>>(() => this.OfsItems, ref ofsItems, value);
      }
      }
      }









      share|improve this question









      $endgroup$




      I'm new to C#, WPF and MVVM and I don't want to make common mistakes right from the beginning and get used to them.

      Already read some similar questions on best practices for WPF/MVVM but none of them included async/await patterns.



      I'm also using MahApps.Metro for UI and MVVM.Light Toolkit.



      Any advise or guidance would be greatly appreciated!



      MainWindow.xaml (cropped)






      [...]
      <Grid>
      <TabControl Controls:TabControlHelper.Underlined="TabPanel">
      <TabItem Header="Programs">
      <Grid DataContext="{Binding ProgramsViewModelMain, Source= {StaticResource Locator}}">
      <Button Content="Refresh" Command="{Binding LoadDataBase}" Height="10" Width="100" VerticalAlignment="Top" HorizontalAlignment="Right"/>
      <Controls:ProgressRing IsActive="{Binding IsLoading}" DockPanel.Dock="Top" Height="60" Width="60" Margin="0 10 0 0"/>
      <DataGrid Margin="0 25 0 0" EnableRowVirtualization="True" GridLinesVisibility="All" Grid.ColumnSpan="2" ItemsSource="{Binding OfsItems}" AutoGenerateColumns="False">
      <DataGrid.Columns>
      <DataGridTextColumn Binding="{Binding ProductionOrder}" Header="Production Order"/>
      <DataGridTextColumn Binding="{Binding OfsTask}" Header="Task"/>
      </DataGrid.Columns>
      <DataGrid.Style>
      <Style TargetType="DataGrid" BasedOn="{StaticResource MetroDataGrid}">
      <Setter Property="Visibility" Value="Hidden"/>
      <Style.Triggers>
      <DataTrigger Binding="{Binding IsLoading}" Value="False">
      <Setter Property="Visibility" Value="Visible"/>
      </DataTrigger>
      </Style.Triggers>
      </Style>
      </DataGrid.Style>
      </DataGrid>
      </Grid>
      </TabItem>
      [...]





      Model



      using GalaSoft.MvvmLight;
      using System.Data.Odbc;
      using System.Collections.ObjectModel;
      using System.Threading.Tasks;
      using System.Collections.Generic;

      namespace CPM_WPF.Model
      {
      public class Ofs : ObservableObject
      {
      public async Task<ObservableCollection<OfsItem>> GetOfsItemsAsync()
      {
      ObservableCollection<OfsItem> ofsdata = new ObservableCollection<OfsItem>();
      List<OfsItem> ofslist = new List<OfsItem>();

      ofslist = await Task.Run(() => DonwloadOfsData()); //get items from database

      foreach (var item in ofslist) //list to observablecollection
      {
      ofsdata.Add(item);
      }
      return ofsdata;
      }

      private List<OfsItem> DonwloadOfsData()
      {
      List<OfsItem> ofslist = new List<OfsItem>();

      OdbcConnection cn;
      OdbcCommand cmd;
      OdbcDataReader dr;

      //connect to database
      string query;
      query = "Select * from tblProductionOrders WHERE Task = 2830";
      cn = new OdbcConnection("Driver={SQL Server};Server=LUDUDSVPSQL1201;Database=OFS460;");
      cmd = new OdbcCommand(query, cn);
      cn.Open();

      dr = cmd.ExecuteReader();

      //read values
      while (dr.Read())
      {
      ofslist.Add(new OfsItem //add items to list
      {
      ProductionOrder = dr.GetInt32(1),
      OfsTask = dr.GetInt32(6)
      });
      };
      return ofslist;
      }

      }
      public class OfsItem : ObservableObject
      {
      private int po;
      private int ofsTask;
      public int ProductionOrder
      {
      get => po;
      set => Set<int>(() => this.ProductionOrder, ref po, value);
      }
      public int OfsTask
      {
      get => ofsTask;
      set => Set<int>(() => this.OfsTask, ref ofsTask, value);
      }
      }
      }


      ViewModel



      using CPM_WPF.Model;
      using GalaSoft.MvvmLight;
      using GalaSoft.MvvmLight.Command;
      using System.Collections.ObjectModel;
      using System.Threading.Tasks;
      using System.Windows.Input;

      namespace CPM_WPF.ViewModel
      {
      public class ProgramsViewModel : ViewModelBase
      {
      public ICommand LoadDataBase { get; private set; }
      public ProgramsViewModel()
      {
      LoadDataBase = new RelayCommand(async () => await LoadDataBaseMethod());
      }

      public async Task LoadDataBaseMethod()
      {
      IsLoading = true;
      Ofs ofs = new Ofs();
      OfsItems = await Task.Run(() => ofs.GetOfsItemsAsync());
      IsLoading = false;
      }

      private ObservableCollection<OfsItem> ofsItems;
      private bool isLoading;

      public bool IsLoading
      {
      get => isLoading;
      set => Set<bool>(() => this.IsLoading, ref isLoading, value);
      }

      public ObservableCollection<OfsItem> OfsItems
      {
      get => ofsItems;
      set => Set<ObservableCollection<OfsItem>>(() => this.OfsItems, ref ofsItems, value);
      }
      }
      }





      [...]
      <Grid>
      <TabControl Controls:TabControlHelper.Underlined="TabPanel">
      <TabItem Header="Programs">
      <Grid DataContext="{Binding ProgramsViewModelMain, Source= {StaticResource Locator}}">
      <Button Content="Refresh" Command="{Binding LoadDataBase}" Height="10" Width="100" VerticalAlignment="Top" HorizontalAlignment="Right"/>
      <Controls:ProgressRing IsActive="{Binding IsLoading}" DockPanel.Dock="Top" Height="60" Width="60" Margin="0 10 0 0"/>
      <DataGrid Margin="0 25 0 0" EnableRowVirtualization="True" GridLinesVisibility="All" Grid.ColumnSpan="2" ItemsSource="{Binding OfsItems}" AutoGenerateColumns="False">
      <DataGrid.Columns>
      <DataGridTextColumn Binding="{Binding ProductionOrder}" Header="Production Order"/>
      <DataGridTextColumn Binding="{Binding OfsTask}" Header="Task"/>
      </DataGrid.Columns>
      <DataGrid.Style>
      <Style TargetType="DataGrid" BasedOn="{StaticResource MetroDataGrid}">
      <Setter Property="Visibility" Value="Hidden"/>
      <Style.Triggers>
      <DataTrigger Binding="{Binding IsLoading}" Value="False">
      <Setter Property="Visibility" Value="Visible"/>
      </DataTrigger>
      </Style.Triggers>
      </Style>
      </DataGrid.Style>
      </DataGrid>
      </Grid>
      </TabItem>
      [...]





      [...]
      <Grid>
      <TabControl Controls:TabControlHelper.Underlined="TabPanel">
      <TabItem Header="Programs">
      <Grid DataContext="{Binding ProgramsViewModelMain, Source= {StaticResource Locator}}">
      <Button Content="Refresh" Command="{Binding LoadDataBase}" Height="10" Width="100" VerticalAlignment="Top" HorizontalAlignment="Right"/>
      <Controls:ProgressRing IsActive="{Binding IsLoading}" DockPanel.Dock="Top" Height="60" Width="60" Margin="0 10 0 0"/>
      <DataGrid Margin="0 25 0 0" EnableRowVirtualization="True" GridLinesVisibility="All" Grid.ColumnSpan="2" ItemsSource="{Binding OfsItems}" AutoGenerateColumns="False">
      <DataGrid.Columns>
      <DataGridTextColumn Binding="{Binding ProductionOrder}" Header="Production Order"/>
      <DataGridTextColumn Binding="{Binding OfsTask}" Header="Task"/>
      </DataGrid.Columns>
      <DataGrid.Style>
      <Style TargetType="DataGrid" BasedOn="{StaticResource MetroDataGrid}">
      <Setter Property="Visibility" Value="Hidden"/>
      <Style.Triggers>
      <DataTrigger Binding="{Binding IsLoading}" Value="False">
      <Setter Property="Visibility" Value="Visible"/>
      </DataTrigger>
      </Style.Triggers>
      </Style>
      </DataGrid.Style>
      </DataGrid>
      </Grid>
      </TabItem>
      [...]






      c# wpf async-await mvvm xaml






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 29 mins ago









      rosi97rosi97

      111




      111






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211881%2fmvvm-databinding-commands-async-mvvm-light%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211881%2fmvvm-databinding-commands-async-mvvm-light%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Terni

          A new problem with tex4ht and tikz

          Sun Ra