Skip to content

Commit

Permalink
Added sample for Lecture 11.
Browse files Browse the repository at this point in the history
  • Loading branch information
jasho committed Apr 16, 2018
1 parent c9c0768 commit c884493
Show file tree
Hide file tree
Showing 72 changed files with 3,085 additions and 0 deletions.
23 changes: 23 additions & 0 deletions Lectures/Lecture_11/Sample/CookBook.App/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings>
<add name="CookBookContext" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=CookBookDB;MultipleActiveResultSets=True;Integrated Security=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
20 changes: 20 additions & 0 deletions Lectures/Lecture_11/Sample/CookBook.App/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Application x:Class="CookBook.App.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:CookBook.App.Converters"
xmlns:app="clr-namespace:CookBook.App"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
<converters:TimeSpanToMinutesConverter x:Key="TimeSpanToMinutesConverter"/>
<app:ViewModelLocator x:Key="ViewModelLocator" />
</ResourceDictionary>
</Application.Resources>
</Application>
11 changes: 11 additions & 0 deletions Lectures/Lecture_11/Sample/CookBook.App/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Windows;

namespace CookBook.App
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
40 changes: 40 additions & 0 deletions Lectures/Lecture_11/Sample/CookBook.App/Commands/RelayCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Windows.Input;

namespace CookBook.App.Commands
{
public class RelayCommand : ICommand
{
private readonly Action<object> executeAction;
private readonly Func<object, bool> canExecuteAction;

public RelayCommand(Action<object> executeAction, Func<object, bool> canExecuteAction = null)
{
this.executeAction = executeAction;
this.canExecuteAction = canExecuteAction;
}

public RelayCommand(Action executeAction, Func<bool> canExecuteAction = null)
: this(p => executeAction(), p => canExecuteAction?.Invoke() ?? true)
{

}

public bool CanExecute(object parameter)
{
return canExecuteAction?.Invoke(parameter) ?? true;
}

public void Execute(object parameter)
{
executeAction?.Invoke(parameter);
}

public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

public event EventHandler CanExecuteChanged;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Windows.Input;
using CookBook.App.ViewModels;
using CookBook.BL;
using CookBook.BL.Messages;
using CookBook.BL.Models;
using CookBook.BL.Repositories;

namespace CookBook.App.Commands
{
public class SaveRecipeCommand : ICommand
{
private readonly RecipeRepository recipeRepository;
private readonly RecipeDetailViewModel viewModel;
private readonly IMessenger messenger;

public SaveRecipeCommand(RecipeRepository recipeRepository, RecipeDetailViewModel viewModel, IMessenger messenger)
{
this.recipeRepository = recipeRepository;
this.viewModel = viewModel;
this.messenger = messenger;
}

public bool CanExecute(object parameter)
{
return viewModel.Detail?.Duration.TotalMinutes > 0;
}

public void Execute(object parameter)
{
if (viewModel.Detail.Id == Guid.Empty)
{
viewModel.Detail = recipeRepository.Insert(viewModel.Detail);
}
else
{
recipeRepository.Update(viewModel.Detail);
}

messenger.Send(new UpdatedRecipeMessage(viewModel.Detail));
}

public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
}
104 changes: 104 additions & 0 deletions Lectures/Lecture_11/Sample/CookBook.App/Controls/CustomButton.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CookBook.App.Controls"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:Converters="clr-namespace:MaterialDesignThemes.Wpf.Converters;assembly=MaterialDesignThemes.Wpf"
x:Class="CookBook.App.Controls.CustomButton"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
HorizontalAlignment="Left"
VerticalAlignment="Top" Width="75" d:LayoutOverrides="Height, LeftPosition, RightPosition, TopPosition, BottomPosition" Style="{DynamicResource CustomButtonStyle}">
<Button.Resources>
<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="{DynamicResource PrimaryHueMidBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryHueMidBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryHueMidForegroundBrush}"/>
<Setter Property="materialDesign:RippleAssist.Feedback" Value="White"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="materialDesign:ShadowAssist.ShadowDepth" Value="Depth1"/>
<Setter Property="FontWeight" Value="Medium"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="16,4"/>
<Setter Property="Height" Value="32"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="grid" Background="{x:Null}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="#FF3A45B7"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#FF3A8FB7"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<AdornerDecorator CacheMode="{Binding (materialDesign:ShadowAssist.CacheMode), RelativeSource={RelativeSource Self}}">
<Grid>
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2" Background="#FF673AB7">
<Border.Effect>
<Binding Path="(materialDesign:ShadowAssist.ShadowDepth)" RelativeSource="{RelativeSource TemplatedParent}">
<Binding.Converter>
<Converters:ShadowConverter/>
</Binding.Converter>
</Binding>
</Border.Effect>
</Border>
<Border Background="{DynamicResource MaterialDesignBackground}" HorizontalAlignment="Left" Opacity="0.4">
<Border.Width>
<MultiBinding UpdateSourceTrigger="Default">
<MultiBinding.Converter>
<Converters:RangeLengthConverter/>
</MultiBinding.Converter>
<Binding Path="(materialDesign:ButtonProgressAssist.Minimum)" RelativeSource="{RelativeSource TemplatedParent}"/>
<Binding Path="(materialDesign:ButtonProgressAssist.Maximum)" RelativeSource="{RelativeSource TemplatedParent}"/>
<Binding Path="(materialDesign:ButtonProgressAssist.Value)" RelativeSource="{RelativeSource TemplatedParent}"/>
<Binding Path="ActualWidth" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ButtonBase}}"/>
</MultiBinding>
</Border.Width>
</Border>
</Grid>
</AdornerDecorator>
<materialDesign:Ripple ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Focusable="False" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="materialDesign:ShadowAssist.Darken" TargetName="border" Value="True"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="materialDesign:ShadowAssist.Darken" TargetName="border" Value="True"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.23"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
</Button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CookBook.App.Controls
{
/// <summary>
/// Interaction logic for CustomButton.xaml
/// </summary>
public partial class CustomButton
{
public CustomButton()
{
InitializeComponent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace CookBook.App.Converters
{
public class NullToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null ? Visibility.Collapsed : Visibility.Visible;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Globalization;
using System.Windows.Data;

namespace CookBook.App.Converters
{
public class TimeSpanToMinutesConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var time = value as TimeSpan?;

return time?.TotalMinutes;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var minutes = value?.ToString();

if (minutes != null)
{
if (int.TryParse(minutes, out var minutesCount))
{
return TimeSpan.FromMinutes(minutesCount);
}
}

return null;
}
}
}
Loading

0 comments on commit c884493

Please sign in to comment.