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


App.xaml — стили и ресурсы
 
<Application x:Class="ConstructionMaterialsApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <!-- Основные стили и ресурсы -->
        <SolidColorBrush x:Key="MainBackground" Color="#FFFFFF"/>
        <SolidColorBrush x:Key="AdditionalBackground" Color="#DAA520"/>
        <SolidColorBrush x:Key="AccentColor" Color="#B8860B"/>
        <SolidColorBrush x:Key="DiscountHighlight" Color="#F4A460"/>
        <SolidColorBrush x:Key="HighlightBlue" Color="#ADD8E6"/>
        <FontFamily x:Key="MainFont">Calibri</FontFamily>
    </Application.Resources>
</Application>
2. MainWindow.xaml — входное окно и навигация
 
<Window x:Class="ConstructionMaterialsApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Вход" Height="300" Width="400"
        ResizeMode="NoResize"
        WindowStartupLocation="CenterScreen"
        FontFamily="{StaticResource MainFont}"
        Background="{StaticResource MainBackground}">
    <Grid Margin="10">
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Spacing="10">
            <TextBlock Text="Логин:" FontWeight="Bold"/>
            <TextBox x:Name="LoginTextBox" Width="200"/>
            <TextBlock Text="Пароль:" FontWeight="Bold"/>
            <PasswordBox x:Name="PasswordBox" Width="200"/>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="10" Margin="0,10,0,0">
                <Button Content="Войти" Width="100" Click="LoginButton_Click"/>
                <Button Content="Гость" Width="100" Click="GuestButton_Click"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>
 
// MainWindow.xaml.cs
using System.Windows;

namespace ConstructionMaterialsApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void LoginButton_Click(object sender, RoutedEventArgs e)
        {
            // Тут должна быть логика проверки логина/пароля из базы
            // Для теста сделаем переход к главному окну с ролью "Пользователь"
            var userRole = "User"; // или "Admin", "Manager" в зависимости от проверки

            var mainAppWindow = new MainAppWindow(userRole);
            mainAppWindow.Show();
            this.Close();
        }

        private void GuestButton_Click(object sender, RoutedEventArgs e)
        {
            var mainAppWindow = new MainAppWindow("Guest");
            mainAppWindow.Show();
            this.Close();
        }
    }
}
3. MainAppWindow.xaml — главное окно с таблицей товаров
 
<Window x:Class="ConstructionMaterialsApp.MainAppWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Система учета строительных материалов" Height="600" Width="1000"
        Background="{StaticResource MainBackground}">
    <DockPanel Margin="10">
        <!-- Верхняя панель с информацией и кнопками -->
        <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" HorizontalAlignment="Right" Margin="0,0,0,10">
            <TextBlock x:Name="UserNameText" VerticalAlignment="Center" Margin="0,0,10,0" FontWeight="Bold"/>
            <Button Content="Выход" Width="80" Click="Logout_Click"/>
        </StackPanel>
        <!-- Основной контент -->
        <StackPanel>
            <!-- Панель поиска и фильтров (можно расширить) -->
            <StackPanel Orientation="Horizontal" Spacing="10" Margin="0,0,0,10">
                <TextBox x:Name="SearchTextBox" Width="200" PlaceholderText="Поиск..."/>
                <Button Content="Фильтр" Width="80" Click="FilterButton_Click"/>
                <Button Content="Очистить" Width="80" Click="ClearFilter_Click"/>
                <!-- Можно добавить комбобокс по производителю, сортировку и др. -->
            </StackPanel>
            <!-- Таблица товаров -->
            <DataGrid x:Name="ProductsDataGrid" AutoGenerateColumns="False" IsReadOnly="True" CanUserSortColumns="False">
                <DataGrid.Columns>
                    <DataGridTemplateColumn Header="Фото" Width="80">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Image Source="{Binding PhotoPath}" Width="70" Height="50"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Header="Наименование" Binding="{Binding Name}"/>
                    <DataGridTextColumn Header="Категория" Binding="{Binding Category}"/>
                    <DataGridTextColumn Header="Производитель" Binding="{Binding Manufacturer}"/>
                    <DataGridTextColumn Header="Поставщик" Binding="{Binding Supplier}"/>
                    <DataGridTextColumn Header="Цена" Binding="{Binding Price}"/>
                    <DataGridTextColumn Header="Ед.изм." Binding="{Binding Unit}"/>
                    <DataGridTextColumn Header="На складе" Binding="{Binding Quantity}"/>
                    <DataGridTextColumn Header="Скидка" Binding="{Binding Discount}"/>
                </DataGrid.Columns>
                <DataGrid.RowStyle>
                    <Style TargetType="DataGridRow">
                        <Style.Triggers>
                            <!-- Если скидка > 12%, подсветка -->
                            <DataTrigger Binding="{Binding Discount}" Value="{x:Static sys:Double}">
                                <DataTrigger.Binding>
                                    <Binding Path="Discount"/>
                                </DataTrigger.Binding>
                                <DataTrigger.Value>
                                    <sys:Double>12</sys:Double>
                                </DataTrigger.Value>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGrid.RowStyle>
            </DataGrid>
            <!-- Кнопки управления (добавить, редактировать, удалить) -->
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0" Spacing="10">
                <Button Content="Добавить товар" Width="120" Click="AddProduct_Click"/>
                <Button Content="Редактировать товар" Width="130" Click="EditProduct_Click"/>
                <Button Content="Удалить товар" Width="120" Click="DeleteProduct_Click"/>
            </StackPanel>
        </StackPanel>
    </DockPanel>
</Window>
 
// MainAppWindow.xaml.cs
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;

namespace ConstructionMaterialsApp
{
    public partial class MainAppWindow : Window
    {
        public ObservableCollection<Product> Products { get; set; }

        public string UserRole { get; set; }

        public MainAppWindow(string role)
        {
            InitializeComponent();
            UserRole = role;
            UserNameText.Text = role == "Guest" ? "Гость" : "Пользователь"; // или имя из базы

            // Инициализация коллекции тестовыми данными
            Products = new ObservableCollection<Product>
            {
                new Product { Id=1, Name="Кирпич", Category="Строительные материалы", Manufacturer="Завод А", Supplier="Поставщик 1", Price=50.0, Unit="шт", Quantity=100, Discount=5, PhotoPath="images/brick.png" },
                new Product { Id=2, Name="Бетон", Category="Строительные материалы", Manufacturer="Завод Б", Supplier="Поставщик 2", Price=3000.0, Unit="м3", Quantity=20, Discount=15, PhotoPath="images/concrete.png" }
            };
            ProductsDataGrid.ItemsSource = Products;

            // Можно добавить обработчики фильтров, сортировки, поиска
        }

        private void Logout_Click(object sender, RoutedEventArgs e)
        {
            var login = new MainWindow();
            login.Show();
            this.Close();
        }

        private void AddProduct_Click(object sender, RoutedEventArgs e)
        {
            // Открытие окна добавления товара
            var addEditWindow = new ProductEditWindow();
            addEditWindow.Owner = this;
            if (addEditWindow.ShowDialog() == true)
            {
                // Добавляем новый товар
                var newProduct = addEditWindow.Product;
                newProduct.Id = Products.Count > 0 ? Products[^1].Id + 1 : 1; // автоматический ID
                Products.Add(newProduct);
            }
        }

        private void EditProduct_Click(object sender, RoutedEventArgs e)
        {
            var selectedProduct = (Product)ProductsDataGrid.SelectedItem;
            if (selectedProduct == null)
            {
                MessageBox.Show("Выберите товар для редактирования.", "Предупреждение", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            var editWindow = new ProductEditWindow(selectedProduct);
            editWindow.Owner = this;
            if (editWindow.ShowDialog() == true)
            {
                // Обновляем выбранный товар
                var updatedProduct = editWindow.Product;
                selectedProduct.Name = updatedProduct.Name;
                selectedProduct.Category = updatedProduct.Category;
                selectedProduct.Manufacturer = updatedProduct.Manufacturer;
                selectedProduct.Supplier = updatedProduct.Supplier;
                selectedProduct.Price = updatedProduct.Price;
                selectedProduct.Unit = updatedProduct.Unit;
                selectedProduct.Quantity = updatedProduct.Quantity;
                selectedProduct.Discount = updatedProduct.Discount;
                selectedProduct.PhotoPath = updatedProduct.PhotoPath;
                ProductsDataGrid.Items.Refresh();
            }
        }

        private void DeleteProduct_Click(object sender, RoutedEventArgs e)
        {
            var selectedProduct = (Product)ProductsDataGrid.SelectedItem;
            if (selectedProduct == null)
            {
                MessageBox.Show("Выберите товар для удаления.", "Предупреждение", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            // Проверка, есть ли заказ с этим товаром - пропустить в примере
            if (MessageBox.Show($"Удалить товар '{selectedProduct.Name}'?", "Подтверждение", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                Products.Remove(selectedProduct);
            }
        }
    }

    public class Product
    {
        public int Id { get; set; }
        public string PhotoPath { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public string Manufacturer { get; set; }
        public string Supplier { get; set; }
        public double Price { get; set; }
        public string Unit { get; set; }
        public int Quantity { get; set; }
        public double Discount { get; set; }
    }
}
4. ProductEditWindow.xaml — форма добавления/редактирования товара
 
<Window x:Class="ConstructionMaterialsApp.ProductEditWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Добавление / Редактирование товара" Height="450" Width="400"
        WindowStartupLocation="CenterOwner"
        FontFamily="{StaticResource MainFont}">
    <Grid Margin="10">
        <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="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="120"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="Наименование:"/>
        <TextBox x:Name="NameTextBox" Grid.Row="0" Grid.Column="1"/>

        <Label Grid.Row="1" Grid.Column="0" Content="Категория:"/>
        <ComboBox x:Name="CategoryComboBox" Grid.Row="1" Grid.Column="1">
            <!-- Добавить категории -->
            <ComboBoxItem Content="Строительные материалы"/>
            <ComboBoxItem Content="Инструменты"/>
            <ComboBoxItem Content="Двери"/>
        </ComboBox>

        <Label Grid.Row="2" Grid.Column="0" Content="Производитель:"/>
        <ComboBox x:Name="ManufacturerComboBox" Grid.Row="2" Grid.Column="1">
            <!-- Производители -->
            <ComboBoxItem Content="Завод А"/>
            <ComboBoxItem Content="Завод Б"/>
        </ComboBox>

        <Label Grid.Row="3" Grid.Column="0" Content="Поставщик:"/>
        <TextBox x:Name="SupplierTextBox" Grid.Row="3" Grid.Column="1"/>

        <Label Grid.Row="4" Grid.Column="0" Content="Цена:"/>
        <TextBox x:Name="PriceTextBox" Grid.Row="4" Grid.Column="1"/>

        <Label Grid.Row="5" Grid.Column="0" Content="Ед.изм.:"/>
        <TextBox x:Name="UnitTextBox" Grid.Row="5" Grid.Column="1"/>

        <Label Grid.Row="6" Grid.Column="0" Content="Количество:"/>
        <TextBox x:Name="QuantityTextBox" Grid.Row="6" Grid.Column="1"/>

        <Label Grid.Row="7" Grid.Column="0" Content="Скидка (%):"/>
        <TextBox x:Name="DiscountTextBox" Grid.Row="7" Grid.Column="1"/>

        <Label Grid.Row="8" Grid.Column="0" Content="Фото:"/>
        <StackPanel Orientation="Horizontal" Grid.Row="8" Grid.Column="1" Spacing="5">
            <Button Content="Выбрать изображение" Click="SelectImage_Click"/>
            <Image x:Name="ProductImage" Width="80" Height="50" Source="images/picture.png"/>
        </StackPanel>

        <StackPanel Grid.Row="9" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right" Spacing="10" Margin="0,10,0,0">
            <Button Content="Сохранить" Width="80" Click="Save_Click"/>
            <Button Content="Отмена" Width="80" Click="Cancel_Click"/>
        </StackPanel>
    </Grid>
</Window>
 
// ProductEditWindow.xaml.cs
using Microsoft.Win32;
using System;
using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;

namespace ConstructionMaterialsApp
{
    public partial class ProductEditWindow : Window
    {
        public Product Product { get; private set; } = new Product();

        private string selectedImagePath = null;

        public ProductEditWindow()
        {
            InitializeComponent();
            DataContext = Product;
        }

        public ProductEditWindow(Product product) : this()
        {
            Product = new Product
            {
                Id = product.Id,
                Name = product.Name,
                Category = product.Category,
                Manufacturer = product.Manufacturer,
                Supplier = product.Supplier,
                Price = product.Price,
                Unit = product.Unit,
                Quantity = product.Quantity,
                Discount = product.Discount,
                PhotoPath = product.PhotoPath
            };
            DataContext = Product;
            // Загрузить изображение
            if (File.Exists(Product.PhotoPath))
            {
                ProductImage.Source = new BitmapImage(new Uri(Product.PhotoPath, UriKind.Absolute));
            }
        }

        private void SelectImage_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new OpenFileDialog();
            dlg.Filter = "Image Files|*.png;*.jpg;*.jpeg";
            if (dlg.ShowDialog() == true)
            {
                // Ограничение размера изображения
                var img = new BitmapImage(new Uri(dlg.FileName));
                if (img.PixelWidth > 300 || img.PixelHeight > 200)
                {
                    MessageBox.Show("Размер изображения не должен превышать 300x200 пикселей.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                selectedImagePath = dlg.FileName;
                ProductImage.Source = new BitmapImage(new Uri(selectedImagePath));
            }
        }

        private void Save_Click(object sender, RoutedEventArgs e)
        {
            // Валидация данных
            if (!double.TryParse(PriceTextBox.Text, out double price) || price < 0)
            {
                MessageBox.Show("Некорректная цена.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (!int.TryParse(QuantityTextBox.Text, out int quantity) || quantity < 0)
            {
                MessageBox.Show("Некорректное количество.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (!double.TryParse(DiscountTextBox.Text, out double discount) || discount < 0)
            {
                MessageBox.Show("Некорректный размер скидки.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            Product.Name = NameTextBox.Text;
            Product.Category = (CategoryComboBox.SelectedItem as ComboBoxItem)?.Content.ToString();
            Product.Manufacturer = (ManufacturerComboBox.SelectedItem as ComboBoxItem)?.Content.ToString();
            Product.Supplier = SupplierTextBox.Text;
            Product.Price = price;
            Product.Unit = UnitTextBox.Text;
            Product.Quantity = quantity;
            Product.Discount = discount;

            // Обработка изображения
            if (selectedImagePath != null)
            {
                var imagesFolder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "images");
                if (!Directory.Exists(imagesFolder))
                    Directory.CreateDirectory(imagesFolder);

                var destPath = System.IO.Path.Combine(imagesFolder, $"product_{Product.Id}.png");
                File.Copy(selectedImagePath, destPath, true);
                Product.PhotoPath = destPath;
            }

            this.DialogResult = true;
            this.Close();
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }
    }
}
Итоги ия