2
\$\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. I 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.

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); 
    }
  }
}
\$\endgroup\$

closed as unclear what you're asking by t3chb0t, Toby Speight, Heslacher, Graipher, Sᴀᴍ Onᴇᴌᴀ Mar 5 at 23:35

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 4
    \$\begingroup\$ Before we can review your code you need to tell us what it is about. Please edit your question and add a description and explain your code in more detail. \$\endgroup\$ – t3chb0t Mar 4 at 15:09