Загрузка данных
Ссылку на system.web.extension
L.get – вывод. DataGet с value get set
MainApi:
DataGet data;
public _mainAPI() => InitializeComponent();
private async void Get(object sender, RoutedEventArgs e) {
try {
data = new JavaScriptSerializer().Deserialize<DataGet>(
await new HttpClient().GetStringAsync("http://localhost:4444/TransferSimulator/fullName"));
lGet.Content = data?.Value; }
catch { MessageBox.Show("Ошибка API"); } }
private void Set(object sender, RoutedEventArgs e) =>
lSet.Content = data?.Value == null ? "Нет данных" : new Regex(@"тут").IsMatch(data.Value) ?
"ФИО Содержит запрещенные символы" : "Валидация прошла успешно";
Текст:
(@"[^а-яА-ЯёЁ\s]"
Номер:
@"^\+7 \d{3} \d{3}-\d{2}-\d{2}$"
Почта:
@"^[^@\s]+@[^@\s]+\.[^@\s]+$"
main
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,10">
<TextBlock Text="Поиск: " VerticalAlignment="Center"/>
<TextBox Name="TbFind" Width="150" TextChanged="UpdateGrid"/>
<TextBlock Text=" Сортировка: " VerticalAlignment="Center"/>
<ComboBox Name="CbSort" Width="120" SelectionChanged="UpdateGrid">
<ComboBoxItem Content="Без сортировки"/>
<ComboBoxItem Content="Цена ↑"/>
<ComboBoxItem Content="Цена ↓"/>
</ComboBox>
</StackPanel>
<DataGrid Name="DgData" Grid.Row="1" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="False">
<Setter Property="Background" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Название" Binding="{Binding Title}" Width="*"/>
<DataGridTextColumn Header="Категория" Binding="{Binding TypeName}"/>
<DataGridTextColumn Header="Цена" Binding="{Binding Cost, StringFormat=N2}"/>
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Name="TbCount" VerticalAlignment="Center" Width="150"/>
<Button Name="BtnAdd" Content="Добавить" Click="BtnAdd_Click" Margin="5,0"/>
<Button Name="BtnEdit" Content="Изменить" Click="BtnEdit_Click" Margin="5,0"/>
<Button Name="BtnDel" Content="Удалить" Click="BtnDel_Click" Margin="5,0"/>
</StackPanel>
</Grid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
if (Helper.RoleID != 1) { BtnAdd.Visibility = Visibility.Collapsed; BtnEdit.Visibility = Visibility.Collapsed; BtnDel.Visibility = Visibility.Collapsed; }
UpdateGrid(null, null);
}
void UpdateGrid(object sender, RoutedEventArgs e)
{
if (DgData == null) return;
string sql = $"SELECT i.ID, i.Title, i.Cost, i.IsActive, t.Title as TypeName FROM Items i JOIN Types t ON i.TypeID = t.ID WHERE i.Title LIKE N'%{TbFind.Text}%'";
if (CbSort.SelectedIndex == 1) sql += " ORDER BY i.Cost ASC";
if (CbSort.SelectedIndex == 2) sql += " ORDER BY i.Cost DESC";
var dt = Helper.Get(sql);
DgData.ItemsSource = dt.DefaultView;
TbCount.Text = $"Записей: {dt.Rows.Count} из {Helper.Get("SELECT ID FROM Items").Rows.Count}";
}
private void BtnAdd_Click(object sender, RoutedEventArgs e) { new EditWindow(0).ShowDialog(); UpdateGrid(null, null); }
private void BtnEdit_Click(object sender, RoutedEventArgs e)
{
if (DgData.SelectedItem is DataRowView r) { new EditWindow((int)r["ID"]).ShowDialog(); UpdateGrid(null, null); }
}
private void BtnDel_Click(object sender, RoutedEventArgs e)
{
if (DgData.SelectedItem is DataRowView r && MessageBox.Show("Удалить?", "!", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
Helper.Exec($"DELETE FROM Items WHERE ID={r["ID"]}"); UpdateGrid(null, null);
}
}
login
<!-- Группировка элементов ввода (требование КОД) -->
<GroupBox Grid.Row="1" Header="Данные учетной записи" Margin="0,0,0,15" Padding="10">
<StackPanel>
<TextBlock Text="Логин:"/>
<TextBox Name="LoginTextBox" TabIndex="1" Margin="0,5,0,10"/>
<TextBlock Text="Пароль:"/>
<PasswordBox Name="UserPasswordBox" TabIndex="2" Margin="0,5,0,5"/>
</StackPanel>
</GroupBox>
<!-- Капча Пазл (Скрыта по умолчанию) -->
<GroupBox Name="CaptchaGroupBox" Grid.Row="2" Header="Соберите пазл" Visibility="Collapsed" Margin="0,0,0,15">
<UniformGrid Columns="2" Rows="2" Width="140" Height="140" Margin="5" HorizontalAlignment="Center">
<!-- RenderTransformOrigin позволяет крутить ровно вокруг центра (0.5, 0.5) -->
<Image Name="CaptchaImage1" Source="/Images/1.png" MouseLeftButtonDown="CaptchaImage_MouseLeftButtonDown" RenderTransformOrigin="0.5,0.5" Cursor="Hand" Stretch="Fill"/>
<Image Name="CaptchaImage2" Source="/Images/2.png" MouseLeftButtonDown="CaptchaImage_MouseLeftButtonDown" RenderTransformOrigin="0.5,0.5" Cursor="Hand" Stretch="Fill"/>
<Image Name="CaptchaImage3" Source="/Images/3.png" MouseLeftButtonDown="CaptchaImage_MouseLeftButtonDown" RenderTransformOrigin="0.5,0.5" Cursor="Hand" Stretch="Fill"/>
<Image Name="CaptchaImage4" Source="/Images/4.png" MouseLeftButtonDown="CaptchaImage_MouseLeftButtonDown" RenderTransformOrigin="0.5,0.5" Cursor="Hand" Stretch="Fill"/>
</UniformGrid>
</GroupBox>
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Name="LoginButton" Content="Войти" Width="100" Margin="5" TabIndex="3" Click="LoginButton_Click" Background="#FFD5E8D4"/>
<Button Name="CancelButton" Content="Отмена" Width="100" Margin="5" TabIndex="4" Click="CancelButton_Click" Background="#FFF8CECC"/>
</StackPanel>
</Grid>
public partial class LoginWindow : Window
{
private int _failedAttempts = 0; // Счетчик неудачных попыток
public LoginWindow()
{
InitializeComponent();
}
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
string userLogin = LoginTextBox.Text.Trim();
string userPassword = UserPasswordBox.Password.Trim();
// 1. Проверка на пустые поля (Обработка ошибок пользователя)
if (string.IsNullOrEmpty(userLogin) || string.IsNullOrEmpty(userPassword))
{
MessageBox.Show("Поля 'Логин' и 'Пароль' обязательны для заполнения.",
"Внимание", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// 2. Проверка капчи (если она видима)
if (CaptchaGroupBox.Visibility == Visibility.Visible)
{
bool isPuzzleSolved = CheckPuzzleState();
if (isPuzzleSolved == false)
{
HandleLoginFailure("Пазл собран неверно. Попробуйте еще раз.");
return;
}
}
try
{
var dt = Helper.Get($"SELECT ID FROM Users WHERE Login=N'{LoginTextBox.Text}' AND Pass=N'{UserPasswordBox.Password}'");
if (dt.Rows.Count > 0)
{
Helper.RoleID = (int)dt.Rows[0][0];
MessageBox.Show("Авторизация прошла успешно!",
"Информация", MessageBoxButton.OK, MessageBoxImage.Information);
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
this.Close();
}
else
{
HandleLoginFailure("Неверный логин или пароль.");
}
}
catch (Exception ex)
{
MessageBox.Show("Ошибка при подключении к базе данных: " + ex.Message,
"Критическая ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
// Метод обработки неудачной попытки входа
private void HandleLoginFailure(string errorMessage)
{
_failedAttempts = _failedAttempts + 1;
if (_failedAttempts >= 3)
{
MessageBox.Show("Система заблокирована из-за превышения попыток авторизации.",
"Блокировка", MessageBoxButton.OK, MessageBoxImage.Error);
LoginButton.IsEnabled = false;
return;
}
MessageBox.Show(errorMessage, "Ошибка входа", MessageBoxButton.OK, MessageBoxImage.Error);
// Показываем капчу после первой ошибки
if (CaptchaGroupBox.Visibility == Visibility.Collapsed)
{
CaptchaGroupBox.Visibility = Visibility.Visible;
}
MixPuzzleImages();
}
// Вращение картинки по клику мыши
private void CaptchaImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Image clickedImage = sender as Image;
// Достаем текущий угол поворота
RotateTransform transform = clickedImage.RenderTransform as RotateTransform;
if (transform == null)
{
transform = new RotateTransform(0);
clickedImage.RenderTransform = transform;
}
// Поворачиваем на 90 градусов
double currentAngle = transform.Angle;
double nextAngle = currentAngle + 90;
if (nextAngle >= 360)
{
nextAngle = 0;
}
transform.Angle = nextAngle;
}
// Метод для случайного перемешивания картинок
private void MixPuzzleImages()
{
Random rnd = new Random();
Image[] images = { CaptchaImage1, CaptchaImage2, CaptchaImage3, CaptchaImage4 };
foreach (Image img in images)
{
// Генерируем случайный угол: 90, 180 или 270 (чтобы не было 0)
int randomMultiplier = rnd.Next(1, 4);
double randomAngle = randomMultiplier * 90;
RotateTransform transform = new RotateTransform(randomAngle);
img.RenderTransform = transform;
}
}
// Метод проверки: все ли картинки стоят под углом 0 градусов
private bool CheckPuzzleState()
{
Image[] images = { CaptchaImage1, CaptchaImage2, CaptchaImage3, CaptchaImage4 };
foreach (Image img in images)
{
RotateTransform transform = img.RenderTransform as RotateTransform;
// Если хоть одна картинка перевернута, возвращаем false
if (transform == null || transform.Angle != 0)
{
return false;
}
}
return true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
}
}
edit
<Grid>
<StackPanel Margin="10">
<TextBlock Text="Название:"/>
<TextBox Name="TbTitle" Margin="0,0,0,5"/>
<TextBlock Text="Цена:"/>
<TextBox Name="TbCost" Margin="0,0,0,5"/>
<TextBlock Text="Категория:"/>
<ComboBox Name="CbType" DisplayMemberPath="Title" SelectedValuePath="ID" Margin="0,0,0,5"/>
<CheckBox Name="CbAct" Content="Активен" IsChecked="True" Margin="0,10"/>
<Button Content="Сохранить" Click="BtnSave_Click"/>
</StackPanel>
</Grid>
int _id;
public EditWindow(int id)
{
InitializeComponent();
_id = id;
CbType.ItemsSource = Helper.Get("SELECT * FROM Types").DefaultView;
if (CbType.Items.Count > 0) CbType.SelectedIndex = 0;
if (_id > 0)
{
var r = Helper.Get($"SELECT * FROM Items WHERE ID={_id}").Rows[0];
TbTitle.Text = r["Title"].ToString();
TbCost.Text = r["Cost"].ToString();
CbType.SelectedValue = r["TypeID"];
CbAct.IsChecked = (bool)r["IsActive"];
}
}
private void BtnSave_Click(object sender, RoutedEventArgs e)
{
if (TbTitle.Text == "") return;
string cost = TbCost.Text.Replace(",", "."); // Точка для SQL
int typeId = (int)CbType.SelectedValue;
bool act = CbAct.IsChecked == true;
string sql = _id == 0
? $"INSERT INTO Items (Title, Cost, TypeID, IsActive) VALUES (N'{TbTitle.Text}', {cost}, {typeId}, '{act}')"
: $"UPDATE Items SET Title=N'{TbTitle.Text}', Cost={cost}, TypeID={typeId}, IsActive='{act}' WHERE ID={_id}";
try { Helper.Exec(sql); Close(); } catch { MessageBox.Show("Ошибка формата цены!"); }
}
}
helper
namespace WpfApp // ЗАМЕНИ НА ИМЯ СВОЕГО ПРОЕКТА
{
public static class Helper
{
// ВАЖНО: Вставь сюда свой сервер!
public static string Cnn = @"Server=DESKTOP-HO3OQM8\SQLEXPRESS;Database=ExamDB;Trusted_Connection=True;";
public static int RoleID = 0; // 1 - Админ, 2 - Юзер
public static DataTable Get(string sql)
{
DataTable dt = new DataTable();
try
{
using (SqlConnection c = new SqlConnection(Cnn))
{
c.Open();
new SqlDataAdapter(sql, c).Fill(dt);
}
}
catch { }
return dt;
}
public static void Exec(string sql)
{
using (SqlConnection c = new SqlConnection(Cnn))
{
c.Open();
new SqlCommand(sql, c).ExecuteNonQuery();
}
}
}
}