Загрузка данных


<Window x:Class="SportShopApp.AddProduct"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Добавление товара"
        Height="720"
        Width="700"
        WindowStartupLocation="CenterScreen"
        ResizeMode="NoResize">

    <ScrollViewer>
        <Grid Margin="20">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <TextBlock Text="Добавление товара"
                       FontSize="26"
                       FontWeight="Bold"
                       Margin="0 0 0 20"/>

            <Grid Grid.Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="180"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <TextBlock Text="Фото товара:" Grid.Row="0"/>
                <StackPanel Grid.Row="0" Grid.Column="1">
                    <Image x:Name="imgProduct"
                           Width="300"
                           Height="200"
                           Stretch="UniformToFill"
                           Source="/Resources/picture.png"
                           Margin="0 0 0 10"/>
                    <Button Content="Выбрать изображение"
                            Width="180"
                            HorizontalAlignment="Left"
                            Click="btnSelectImage_Click"/>
                </StackPanel>

                <TextBlock Text="Артикул:" Grid.Row="1" Margin="0 15 0 0"/>
                <TextBox x:Name="tbArticle" Grid.Row="1" Grid.Column="1" Margin="0 15 0 0"/>

                <TextBlock Text="Наименование:" Grid.Row="2" Margin="0 10 0 0"/>
                <TextBox x:Name="tbName" Grid.Row="2" Grid.Column="1" Margin="0 10 0 0"/>

                <TextBlock Text="Категория:" Grid.Row="3" Margin="0 10 0 0"/>
                <ComboBox x:Name="cbCategory" Grid.Row="3" Grid.Column="1" Margin="0 10 0 0"
                          DisplayMemberPath="Name" SelectedValuePath="Id"/>

                <TextBlock Text="Описание:" Grid.Row="4" Margin="0 10 0 0"/>
                <TextBox x:Name="tbDescription" Grid.Row="4" Grid.Column="1" Margin="0 10 0 0"
                         Height="70" TextWrapping="Wrap" AcceptsReturn="True"/>

                <TextBlock Text="Производитель:" Grid.Row="5" Margin="0 10 0 0"/>
                <ComboBox x:Name="cbManufacturer" Grid.Row="5" Grid.Column="1" Margin="0 10 0 0"
                          DisplayMemberPath="Name" SelectedValuePath="Id"/>

                <TextBlock Text="Поставщик:" Grid.Row="6" Margin="0 10 0 0"/>
                <ComboBox x:Name="cbProvider" Grid.Row="6" Grid.Column="1" Margin="0 10 0 0"
                          DisplayMemberPath="Name" SelectedValuePath="Id"/>

                <TextBlock Text="Цена:" Grid.Row="7" Margin="0 10 0 0"/>
                <TextBox x:Name="tbPrice" Grid.Row="7" Grid.Column="1" Margin="0 10 0 0"/>

                <TextBlock Text="Единица измерения:" Grid.Row="8" Margin="0 10 0 0"/>
                <ComboBox x:Name="cbMeasure" Grid.Row="8" Grid.Column="1" Margin="0 10 0 0"
                          DisplayMemberPath="Name" SelectedValuePath="Id"/>

                <TextBlock Text="Количество:" Grid.Row="9" Margin="0 10 0 0"/>
                <TextBox x:Name="tbAmount" Grid.Row="9" Grid.Column="1" Margin="0 10 0 0"/>

                <TextBlock Text="Скидка:" Grid.Row="10" Margin="0 10 0 0"/>
                <TextBox x:Name="tbDiscount" Grid.Row="10" Grid.Column="1" Margin="0 10 0 0"/>
            </Grid>

            <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 25 0 0">
                <Button Content="Сохранить"
                        Width="130"
                        Height="35"
                        Margin="0 0 10 0"
                        Click="btnSave_Click"/>

                <Button Content="Отмена"
                        Width="130"
                        Height="35"
                        Click="btnCancel_Click"/>
            </StackPanel>
        </Grid>
    </ScrollViewer>
</Window>


using Microsoft.Win32;
using SportShopApp.Model;
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media.Imaging;

namespace SportShopApp
{
    public partial class AddProduct : Window
    {
        private string selectedImagePath;
        private string savedImageRelativePath;

        public AddProduct()
        {
            InitializeComponent();
            LoadComboBoxes();
        }

        private void LoadComboBoxes()
        {
            cbCategory.ItemsSource = App.DBCon.Category.OrderBy(x => x.Name).ToList();
            cbManufacturer.ItemsSource = App.DBCon.Manufacturer.OrderBy(x => x.Name).ToList();
            cbProvider.ItemsSource = App.DBCon.Provider.OrderBy(x => x.Name).ToList();
            cbMeasure.ItemsSource = App.DBCon.Measure.OrderBy(x => x.Name).ToList();

            cbCategory.SelectedIndex = 0;
            cbManufacturer.SelectedIndex = 0;
            cbProvider.SelectedIndex = 0;
            cbMeasure.SelectedIndex = 0;
        }

        private void btnSelectImage_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog
            {
                Filter = "Изображения|*.jpg;*.jpeg;*.png;*.bmp"
            };

            if (dialog.ShowDialog() == true)
            {
                selectedImagePath = dialog.FileName;
                imgProduct.Source = new BitmapImage(new Uri(selectedImagePath));
            }
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            if (!ValidateProduct())
            {
                return;
            }

            try
            {
                string article = tbArticle.Text.Trim();

                bool articleExists = App.DBCon.Product.Any(p => p.Article == article);

                if (articleExists)
                {
                    MessageBox.Show(
                        "Товар с таким артикулом уже существует.",
                        "Ошибка",
                        MessageBoxButton.OK,
                        MessageBoxImage.Error);
                    return;
                }

                ProductName productName = new ProductName
                {
                    Name = tbName.Text.Trim()
                };

                App.DBCon.ProductName.Add(productName);
                App.DBCon.SaveChanges();

                if (!string.IsNullOrWhiteSpace(selectedImagePath))
                {
                    savedImageRelativePath = SaveProductImage(selectedImagePath);
                }

                Product product = new Product
                {
                    Article = article,
                    ProductNameId = productName.Id,
                    CategoryId = (int)cbCategory.SelectedValue,
                    ManufacturerId = (int)cbManufacturer.SelectedValue,
                    ProviderId = (int)cbProvider.SelectedValue,
                    MeasureId = (int)cbMeasure.SelectedValue,
                    Description = tbDescription.Text.Trim(),
                    Price = decimal.Parse(tbPrice.Text),
                    Amount = int.Parse(tbAmount.Text),
                    Discount = byte.Parse(tbDiscount.Text),
                    Image = savedImageRelativePath
                };

                App.DBCon.Product.Add(product);
                App.DBCon.SaveChanges();

                MessageBox.Show(
                    "Товар успешно добавлен.",
                    "Информация",
                    MessageBoxButton.OK,
                    MessageBoxImage.Information);

                DialogResult = true;
                Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    $"Не удалось добавить товар.\n\nОшибка: {ex.Message}",
                    "Ошибка",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
            }
        }

        private bool ValidateProduct()
        {
            if (string.IsNullOrWhiteSpace(tbArticle.Text))
            {
                ShowValidationError("Введите артикул товара.");
                return false;
            }

            if (string.IsNullOrWhiteSpace(tbName.Text))
            {
                ShowValidationError("Введите наименование товара.");
                return false;
            }

            if (cbCategory.SelectedValue == null ||
                cbManufacturer.SelectedValue == null ||
                cbProvider.SelectedValue == null ||
                cbMeasure.SelectedValue == null)
            {
                ShowValidationError("Заполните все выпадающие списки.");
                return false;
            }

            if (!decimal.TryParse(tbPrice.Text, out decimal price) || price < 0)
            {
                ShowValidationError("Цена должна быть числом и не может быть отрицательной.");
                return false;
            }

            if (!int.TryParse(tbAmount.Text, out int amount) || amount < 0)
            {
                ShowValidationError("Количество должно быть целым числом и не может быть отрицательным.");
                return false;
            }

            if (!byte.TryParse(tbDiscount.Text, out byte discount) || discount > 100)
            {
                ShowValidationError("Скидка должна быть числом от 0 до 100.");
                return false;
            }

            return true;
        }

        private void ShowValidationError(string message)
        {
            MessageBox.Show(
                message,
                "Ошибка заполнения",
                MessageBoxButton.OK,
                MessageBoxImage.Warning);
        }

        private string SaveProductImage(string sourcePath)
        {
            string imagesFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images");

            if (!Directory.Exists(imagesFolder))
            {
                Directory.CreateDirectory(imagesFolder);
            }

            string fileName = $"{Guid.NewGuid()}.jpg";
            string fullSavePath = Path.Combine(imagesFolder, fileName);

            BitmapImage sourceImage = new BitmapImage();
            sourceImage.BeginInit();
            sourceImage.CacheOption = BitmapCacheOption.OnLoad;
            sourceImage.UriSource = new Uri(sourcePath);
            sourceImage.EndInit();

            TransformedBitmap resizedImage = ResizeImage(sourceImage, 300, 200);

            JpegBitmapEncoder encoder = new JpegBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(resizedImage));

            using (FileStream stream = new FileStream(fullSavePath, FileMode.Create))
            {
                encoder.Save(stream);
            }

            return Path.Combine("Images", fileName);
        }

        private TransformedBitmap ResizeImage(BitmapSource source, int maxWidth, int maxHeight)
        {
            double scaleX = (double)maxWidth / source.PixelWidth;
            double scaleY = (double)maxHeight / source.PixelHeight;
            double scale = Math.Min(scaleX, scaleY);

            return new TransformedBitmap(
                source,
                new System.Windows.Media.ScaleTransform(scale, scale));
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
    }
}


private void btnAdd_Click(object sender, RoutedEventArgs e)
{
    AddProduct addProductWindow = new AddProduct();

    if (addProductWindow.ShowDialog() == true)
    {
        LoadProducts();
    }
}

<Button x:Name="btnAdd"
        Content="Добавить товар"
        Click="btnAdd_Click"/>