Загрузка данных
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();
}
}
}
Итоги ия