Application ready before dependency injction

This commit is contained in:
2022-08-23 23:31:45 +02:00
parent d3b7ff17be
commit 2b42691434
15 changed files with 234 additions and 78 deletions

View File

@ -20,6 +20,7 @@ namespace YouTubeViewers.EntityFramework.Commands
public async Task Execute(YouTubeViewer youTubeViewer) public async Task Execute(YouTubeViewer youTubeViewer)
{ {
using (YouTubeViewersDbContext context = _contextFactory.Create()) using (YouTubeViewersDbContext context = _contextFactory.Create())
{ {
YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto() YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto()

View File

@ -21,7 +21,6 @@ namespace YouTubeViewers.EntityFramework.Commands
{ {
using (YouTubeViewersDbContext context = _contextFactory.Create()) using (YouTubeViewersDbContext context = _contextFactory.Create())
{ {
await Task.Delay(5000);
YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto() YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto()
{ {
Id = id, Id = id,

View File

@ -20,6 +20,7 @@ namespace YouTubeViewers.EntityFramework.Commands
public async Task Execute(YouTubeViewer youTubeViewer) public async Task Execute(YouTubeViewer youTubeViewer)
{ {
using (YouTubeViewersDbContext context = _contextFactory.Create()) using (YouTubeViewersDbContext context = _contextFactory.Create())
{ {
YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto() YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto()

View File

@ -8,8 +8,12 @@
<Style x:Key="PageHeader" TargetType="TextBlock" > <Style x:Key="PageHeader" TargetType="TextBlock" >
<Setter Property="FontSize" Value="32" /> <Setter Property="FontSize" Value="32" />
</Style> </Style>
<Style x:Key="ErrorMessage" TargetType="TextBlock" >
<Setter Property="Foreground" Value="Red" />
</Style>
<Style TargetType="Button"> <Style TargetType="Button">
<Setter Property="Foreground" Value="White" /> <Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="#547AFF" /> <Setter Property="Background" Value="#547AFF" />

View File

@ -24,6 +24,7 @@ namespace YouTubeViewers.WPF.Commands
public override async Task ExecuteAsync(object? parameter) public override async Task ExecuteAsync(object? parameter)
{ {
YouTubeViewerDetailsFormViewModel formViewModel = _addYouTubeViewerViewModel.YouTubeViewerDetailsFormViewModel; YouTubeViewerDetailsFormViewModel formViewModel = _addYouTubeViewerViewModel.YouTubeViewerDetailsFormViewModel;
formViewModel.ErrorMessage = null;
formViewModel.IsSubmitting = true; formViewModel.IsSubmitting = true;
YouTubeViewer youTubeViewer = new YouTubeViewer( YouTubeViewer youTubeViewer = new YouTubeViewer(
Guid.NewGuid(), Guid.NewGuid(),
@ -39,7 +40,7 @@ namespace YouTubeViewers.WPF.Commands
} }
catch (Exception) catch (Exception)
{ {
throw; formViewModel.ErrorMessage = "Failed to add YouTube Viewer. Please try again later.";
} }
finally finally
{ {

View File

@ -25,6 +25,8 @@ namespace YouTubeViewers.WPF.Commands
public override async Task ExecuteAsync(object? parameter) public override async Task ExecuteAsync(object? parameter)
{ {
_youTubeViewersListingItemViewModel.ErrorMessage = null;
_youTubeViewersListingItemViewModel.IsDeleting = true;
YouTubeViewer youTubeViewer = _youTubeViewersListingItemViewModel.YouTubeViewer; YouTubeViewer youTubeViewer = _youTubeViewersListingItemViewModel.YouTubeViewer;
try try
{ {
@ -32,7 +34,11 @@ namespace YouTubeViewers.WPF.Commands
} }
catch (Exception) catch (Exception)
{ {
throw; _youTubeViewersListingItemViewModel.ErrorMessage = "Failed to delete YouTube viewer. Please try again later.";
}
finally
{
_youTubeViewersListingItemViewModel.IsDeleting = false;
} }
} }
} }

View File

@ -24,6 +24,7 @@ namespace YouTubeViewers.WPF.Commands
public override async Task ExecuteAsync(object? parameter) public override async Task ExecuteAsync(object? parameter)
{ {
YouTubeViewerDetailsFormViewModel formViewModel = _editYouTubeViewerViewModel.YouTubeViewerDetailsFormViewModel; YouTubeViewerDetailsFormViewModel formViewModel = _editYouTubeViewerViewModel.YouTubeViewerDetailsFormViewModel;
formViewModel.ErrorMessage = null;
formViewModel.IsSubmitting = true; formViewModel.IsSubmitting = true;
YouTubeViewer youTubeViewer = new YouTubeViewer( YouTubeViewer youTubeViewer = new YouTubeViewer(
_editYouTubeViewerViewModel.YouTubeViewerId, _editYouTubeViewerViewModel.YouTubeViewerId,
@ -39,7 +40,7 @@ namespace YouTubeViewers.WPF.Commands
} }
catch (Exception) catch (Exception)
{ {
throw; formViewModel.ErrorMessage = "Failed to update YouTube Viewer. Please try again later.";
} }
finally finally
{ {

View File

@ -21,6 +21,7 @@ namespace YouTubeViewers.WPF.Commands
public override async Task ExecuteAsync(object? parameter) public override async Task ExecuteAsync(object? parameter)
{ {
_youTubeViewersViewModel.ErrorMessage = null;
_youTubeViewersViewModel.IsLoading = true; _youTubeViewersViewModel.IsLoading = true;
try try
@ -29,7 +30,7 @@ namespace YouTubeViewers.WPF.Commands
} }
catch (Exception) catch (Exception)
{ {
throw; _youTubeViewersViewModel.ErrorMessage = "Failed to load YouTube viewers. Please restart the application.";
} }
finally finally
{ {

View File

@ -7,10 +7,14 @@
xmlns:custom="clr-namespace:LoadingSpinnerControl;assembly=LoadingSpinnerControl" xmlns:custom="clr-namespace:LoadingSpinnerControl;assembly=LoadingSpinnerControl"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</UserControl.Resources>
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid Grid.IsSharedSizeScope="True"> <Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@ -66,5 +70,12 @@
Style="{StaticResource ButtonSecondary}"/> Style="{StaticResource ButtonSecondary}"/>
<custom:LoadingSpinner IsLoading="{Binding IsSubmitting}" Diameter="25" Thickness="2"/> <custom:LoadingSpinner IsLoading="{Binding IsSubmitting}" Diameter="25" Thickness="2"/>
</WrapPanel> </WrapPanel>
<TextBlock
Grid.Row="2"
Margin="0 15 0 0"
Style="{StaticResource ErrorMessage}"
Text="{Binding ErrorMessage}"
Visibility="{Binding HasErrorMessage, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -5,76 +5,115 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:YouTubeViewers.WPF.Components" xmlns:local="clr-namespace:YouTubeViewers.WPF.Components"
xmlns:custom="clr-namespace:DropdownMenuControl;assembly=DropdownMenuControl" xmlns:custom="clr-namespace:DropdownMenuControl;assembly=DropdownMenuControl"
xmlns:loadingspinner="clr-namespace:LoadingSpinnerControl;assembly=LoadingSpinnerControl"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</UserControl.Resources>
<Border Padding="10" TextBlock.FontSize="16"> <Border Padding="10" TextBlock.FontSize="16">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="{Binding UserName}"/>
<TextBlock
FontSize="10"
Style="{StaticResource ErrorMessage}"
Text="{Binding ErrorMessage}"
Visibility="{Binding HasErrorMessage, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</StackPanel>
<TextBlock Grid.Column="0" Text="{Binding UserName}"/> <Grid Grid.Column="1" Margin="10 0 0 0">
<Grid VerticalAlignment="Center">
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsDeleting}" Value="true">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<loadingspinner:LoadingSpinner Diameter="20" IsLoading="True" Thickness="2"/>
</Grid>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsDeleting}" Value="false">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<custom:DropdownMenu x:Name="dropdown" Grid.Column="1" Margin="10 0 0 0"> <custom:DropdownMenu x:Name="dropdown" >
<Border <Border
Background="White" Background="White"
BorderThickness="1" BorderThickness="1"
BorderBrush="Gray"> BorderBrush="Gray">
<StackPanel MinWidth="125"> <StackPanel MinWidth="125">
<StackPanel.Resources> <StackPanel.Resources>
<Style TargetType="Button"> <Style TargetType="Button">
<Setter Property="Background" Value="#f0f0f0"/> <Setter Property="Background" Value="#f0f0f0"/>
<Setter Property="Foreground" Value="Black"/> <Setter Property="Foreground" Value="Black"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/> <Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="20 10"/> <Setter Property="Padding" Value="20 10"/>
<Setter Property="Cursor" Value="Hand"/> <Setter Property="Cursor" Value="Hand"/>
<EventSetter Event="Click" Handler="Button_Click"/> <EventSetter Event="Click" Handler="Button_Click"/>
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="Button"> <ControlTemplate TargetType="Button">
<Border <Border
Margin="{TemplateBinding Margin}" Margin="{TemplateBinding Margin}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"> Background="{TemplateBinding Background}">
<ContentPresenter /> <ContentPresenter />
</Border> </Border>
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
To="#c7c7c7"
Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
To="#f0f0f0"
Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<Button Content="Edit" Command="{Binding EditCommand}"/>
<Button Content="Delete" Command="{Binding DeleteCommand}"/>
</StackPanel>
</Border>
</custom:DropdownMenu>
</Grid>
</Grid>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
To="#c7c7c7"
Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
To="#f0f0f0"
Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<Button Content="Edit" Command="{Binding EditCommand}"/>
<Button Content="Delete" Command="{Binding DeleteCommand}"/>
</StackPanel>
</Border>
</custom:DropdownMenu>
</Grid> </Grid>
</Border> </Border>
</UserControl> </UserControl>

View File

@ -59,6 +59,25 @@ public class YouTubeViewerDetailsFormViewModel : ViewModelBase
#endregion IsSubmitting #endregion IsSubmitting
#region ErrorMessage
private string _errorMessage;
public string ErrorMessage
{
get { return _errorMessage; }
set
{
_errorMessage = value;
OnPropertyChanged(nameof(ErrorMessage));
OnPropertyChanged(nameof(HasErrorMessage));
}
}
#endregion ErrorMessage
public bool HasErrorMessage => !string.IsNullOrEmpty(ErrorMessage);
public bool CanSubmit => !string.IsNullOrEmpty(UserName); public bool CanSubmit => !string.IsNullOrEmpty(UserName);
public ICommand SubmitCommand { get; } public ICommand SubmitCommand { get; }
public ICommand CancelCommand { get; } public ICommand CancelCommand { get; }

View File

@ -20,6 +20,35 @@ namespace YouTubeViewers.WPF.ViewModels
public string UserName => YouTubeViewer.Username; public string UserName => YouTubeViewer.Username;
#region IsDeleting
private bool _isDeleting;
public bool IsDeleting
{
get { return _isDeleting; }
set { _isDeleting = value; OnPropertyChanged(); }
}
#endregion IsDeleting
#region ErrorMessage
private string _errorMessage;
public string ErrorMessage
{
get { return _errorMessage; }
set
{
_errorMessage = value;
OnPropertyChanged(nameof(ErrorMessage));
OnPropertyChanged(nameof(HasErrorMessage));
}
}
#endregion ErrorMessage
public bool HasErrorMessage => !string.IsNullOrEmpty(ErrorMessage);
public ICommand EditCommand { get; } public ICommand EditCommand { get; }
public ICommand DeleteCommand { get; } public ICommand DeleteCommand { get; }

View File

@ -29,6 +29,23 @@ namespace YouTubeViewers.WPF.ViewModels
} }
} }
#region ErrorMessage
private string _errorMessage;
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value;
OnPropertyChanged(nameof(ErrorMessage));
OnPropertyChanged(nameof(HasErrorMessage));
}
}
#endregion ErrorMessage
public bool HasErrorMessage => !string.IsNullOrEmpty(ErrorMessage);
public ICommand LoadYouTubeViewersCommand { get; } public ICommand LoadYouTubeViewersCommand { get; }
public ICommand AddYouTubeViewersCommand { get; } public ICommand AddYouTubeViewersCommand { get; }
public YouTubeViewersViewModel(YouTubeViewersStore youTubeViewersStore, SelectedYouTubeViewerStore _selectedYouTubeViewerStore, ModalNavigationStore modalNavigationStore) public YouTubeViewersViewModel(YouTubeViewersStore youTubeViewersStore, SelectedYouTubeViewerStore _selectedYouTubeViewerStore, ModalNavigationStore modalNavigationStore)

View File

@ -6,7 +6,9 @@
xmlns:local="clr-namespace:YouTubeViewers.WPF.Views" xmlns:local="clr-namespace:YouTubeViewers.WPF.Views"
xmlns:components="clr-namespace:YouTubeViewers.WPF.Components" xmlns:components="clr-namespace:YouTubeViewers.WPF.Components"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800"
Width="400"
>
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>

View File

@ -34,25 +34,50 @@
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Grid.Style> </Grid.Style>
<Grid.RowDefinitions> <Grid>
<RowDefinition Height="Auto"/> <Grid.Style>
<RowDefinition Height="*"/> <Style TargetType="Grid">
</Grid.RowDefinitions> <Setter Property="Visibility" Value="Collapsed"/>
<Grid Grid.Row="0"> <Style.Triggers>
<Grid.ColumnDefinitions> <DataTrigger Binding="{Binding HasErrorMessage}" Value="True">
<ColumnDefinition Width="*"/> <Setter Property="Visibility" Value="Visible"/>
<ColumnDefinition Width="Auto"/> </DataTrigger>
</Grid.ColumnDefinitions> </Style.Triggers>
<TextBlock Grid.Column="0" Style="{StaticResource PageHeader}" Text="YouTube Viewers" /> </Style>
<Button Grid.Column="1" Content="Add" FontSize="16" Command="{Binding AddYouTubeViewersCommand}"/> </Grid.Style>
<TextBlock TextAlignment="Center" VerticalAlignment="Center" Style="{StaticResource ErrorMessage}" Text="{Binding ErrorMessage}"/>
</Grid> </Grid>
<Grid Grid.Row="1" Margin="0 20 0 0"> <Grid>
<Grid.ColumnDefinitions> <Grid.Style>
<ColumnDefinition Width="*"/> <Style TargetType="Grid">
<ColumnDefinition Width="2*"/> <Setter Property="Visibility" Value="Collapsed"/>
</Grid.ColumnDefinitions> <Style.Triggers>
<components:YouTubeViewersListing Grid.Column="0" DataContext="{Binding YouTubeViewersListingViewModel}"/> <DataTrigger Binding="{Binding HasErrorMessage}" Value="false">
<components:YouTubeViewersDetails Grid.Column="1" Margin="20 0 0 0" DataContext="{Binding YouTubeViewersDetailsViewModel}"/> <Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Style="{StaticResource PageHeader}" Text="YouTube Viewers" />
<Button Grid.Column="1" Content="Add" FontSize="16" Command="{Binding AddYouTubeViewersCommand}"/>
</Grid>
<Grid Grid.Row="1" Margin="0 20 0 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<components:YouTubeViewersListing Grid.Column="0" DataContext="{Binding YouTubeViewersListingViewModel}"/>
<components:YouTubeViewersDetails Grid.Column="1" Margin="20 0 0 0" DataContext="{Binding YouTubeViewersDetailsViewModel}"/>
</Grid>
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>