"

5. Build MultipleSuggestions Window

Create MealPlan and ViewModel classes

MealPlan class is for containing breakfast, lunch, and dinner dish names for one day. ViewModel holds a list of MealPlan instances that will be bound and will update  the data grid for suggestions.

Create a class named MealPlan and put this code.

internal class MealPlan
{
    public string Breakfast { get; set; }
    public string Lunch { get; set; }
    public string Dinner { get; set; }
}

Create a class named ViewModel and put this code.

internal class ViewModel
{
    public IList MealPlans { get; set; }
}

Add UI Components

  1. Go to MultipleSuggestions.xaml file.
  2. Modify backBtn and add a button (getSuggestionBtn), slider (daysSlider), data grid, and text blocks. Check the provided code below to understand better. It is for the most outer grid.
    <Grid>
        <Button x:Name="backBtn" Content="Back to Main" HorizontalAlignment="Left" Margin="26,26,0,0" VerticalAlignment="Top" Width="140" Height="45" Click="backBtn_Click"/>
        <DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" Height="368" Margin="354,26,0,0" VerticalAlignment="Top" Width="417">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Breakfast" Width="*"/>
                <DataGridTextColumn Header="Lunch"  Width="*"/>
                <DataGridTextColumn Header="Dinner"  Width="*"/>
            </DataGrid.Columns>
        </DataGrid>
        <Slider x:Name="daysSlider" Minimum="1" Maximum="30" IsSnapToTickEnabled="True" TickFrequency="1" HorizontalAlignment="Left" Margin="26,166,0,0" VerticalAlignment="Top" Height="19" Width="306"/>
        <Button x:Name="getSuggestionBtn" Content="Get Suggestions" HorizontalAlignment="Left" Margin="26,244,0,0" VerticalAlignment="Top" Width="306" Height="53" />
        <TextBlock Text="" HorizontalAlignment="Left" Margin="136,190,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="25"/>
        <TextBlock Text="Day(s)" HorizontalAlignment="Left" Margin="161,190,0,0" TextWrapping="Wrap" VerticalAlignment="Top"/>
    </Grid>
    

Add Database Context

This part is the same as the last chapter.

  1. Go to MultipleSuggestions.xaml.cs file.
  2. Under declaration for ParentWindow, declare a private MealSuggestionContainer field named _context.
    private MealSuggestionContainer _context;
    
  3. Inside of the constructor, create a new MealSuggestionContainer for _context.
    //create data context
    _context = new MealSuggestionContainer();
    

Add Controller

  1. Go to MultipleSuggestions.xaml.cs file.
  2. Add variables needed for getSuggestionBtn_Click function under declaration for _context.
    private ViewModel viewModel;
    private int lastBreakfastDish = -1;
    private int lastLunchDish = -1;
    private int lastDinnerDish = -1;
    
  3. Add the code below for viewModel to the constructor. Note that _context is used to communicate with the database while viewModel is for populating the UI components. Data retrieved using _context is stored in viewModel, and viewModel feeds data to the data grid on this window.
    //set viewModel as data context and create its MealPlans
    viewModel = new ViewModel();
    viewModel.MealPlans = new ObservableCollection();
    this.DataContext = this.viewModel;
    
  4. Add getSuggestionBtn_Click function. Check the code below.
    private void getSuggestionBtn_Click(object sender, RoutedEventArgs e)
    {
        Dish[] breakfasts;
        Dish[] nonBreakfasts;
    
        //get dishes from database and store them in arrays
        try
        {
            var dishes = from d in _context.Dishes
                            where d.Breakfast == true
                            select d;
    
            breakfasts = dishes.ToArray();
    
            dishes = from d in _context.Dishes
                        where d.Breakfast == false
                        select d;
    
            nonBreakfasts = dishes.ToArray();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            return;
        }
    
        //when there is not enough dish
        if (nonBreakfasts.Length == 0 || breakfasts.Length == 0)
        {
            MessageBox.Show("Please add dishes (at least 1 breakfast & 1 lunch or dinner) first.");
            return;
        }
    
        //clear previous suggestions
        viewModel.MealPlans.Clear();
    
        //generate suggestions
        Random random = new Random();
        for (int i = 0; i < daysSlider.Value; i++) { int breakfastIndex = random.Next(0, breakfasts.Length); //if enough candidates, avoid getting same dish as last breakfast if (breakfasts.Length > 1)
            {
                while (breakfastIndex == lastBreakfastDish)
                {
                    breakfastIndex = random.Next(0, breakfasts.Length);
                }
            }
            lastBreakfastDish = breakfastIndex;
    
            int lunchIndex = random.Next(0, nonBreakfasts.Length);
            //if enough candidates, avoid getting same dish as last lunch
            if (nonBreakfasts.Length > 1)
            {
                while (lunchIndex == lastLunchDish)
                {
                    lunchIndex = random.Next(0, nonBreakfasts.Length);
                }
            }
            lastLunchDish = lunchIndex;
    
            int dinnerIndex = random.Next(0, nonBreakfasts.Length);
            //if enough candidates, avoid getting same dish as last dinner or this day's lunch
            if (nonBreakfasts.Length > 2)
            {
                while (dinnerIndex == lastDinnerDish || dinnerIndex == lunchIndex)
                {
                    dinnerIndex = random.Next(0, nonBreakfasts.Length);
                }
            }
            lastDinnerDish = dinnerIndex;
    
            //create new mealPlan and add it to viewModel's MealPlans
            MealPlan mealPlan = new MealPlan
            {
                Breakfast = breakfasts[breakfastIndex].Name,
                Lunch = nonBreakfasts[lunchIndex].Name,
                Dinner = nonBreakfasts[dinnerIndex].Name
            };
    
            viewModel.MealPlans.Add(mealPlan);
    
        }
    
    }
    
  5. Go to MultipleSuggestions.xaml file.
  6. Add Click="getSuggestionBtn_Click" for getSuggestionBtn button.
  7. Add ItemsSource="{Binding MealPlans}" for the data grid.
  8. Add Binding="{Binding Breakfast}", Binding="{Binding Lunch}", Binding="{Binding Dinner}" for each data grid text column.
  9. Replace Text property of the empty text block with Text="{Binding ElementName=daysSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}".

Check Your Code

After following this chapter, your app should be able to:

  • Provide a list of meal plan suggestions for days (number of days provided using the slider) on the data grid while avoiding getting the same breakfast as the breakfast on the day before (applies the same to lunch and dinner).

License

OER Lab guide Centennial College Copyright © by Centennial College OER Lab Students. All Rights Reserved.