Загрузка данных
Да. Ниже — полностью исправленный код под C# 7.3 без using var, без новых сокращённых конструкций, которые требуют более новой версии языка.
Я даю полные версии файлов, чтобы можно было просто заменить.
⸻
1. App.xaml
<Application x:Class="LabApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
⸻
2. App.xaml.cs
using System.Windows;
namespace LabApp
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
LoginWindow window = new LoginWindow();
window.Show();
}
}
}
⸻
3. LoginWindow.xaml
<Window x:Class="LabApp.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Авторизация" Height="280" Width="420" WindowStartupLocation="CenterScreen">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Логин"/>
<TextBox x:Name="tbLogin" Margin="0,25,0,10" Height="30"/>
<TextBlock Grid.Row="1" Text="Пароль"/>
<PasswordBox x:Name="pbPassword" Grid.Row="1" Margin="0,25,0,10" Height="30"/>
<Button Grid.Row="2" Content="Войти" Height="35" Margin="0,10,0,0" Click="LoginClick"/>
<TextBlock x:Name="tbMsg" Grid.Row="3" Margin="0,15,0,0" TextWrapping="Wrap"/>
</Grid>
</Window>
⸻
4. LoginWindow.xaml.cs
using System;
using System.Data;
using System.Windows;
using MySqlConnector;
namespace LabApp
{
public partial class LoginWindow : Window
{
private string cs = "Server=localhost;Port=3306;Database=lab_accounting_db;Uid=root;Pwd=12345;";
public LoginWindow()
{
InitializeComponent();
}
private DataTable Q(string sql, params MySqlParameter[] p)
{
DataTable t = new DataTable();
using (MySqlConnection c = new MySqlConnection(cs))
{
using (MySqlCommand m = new MySqlCommand(sql, c))
{
if (p != null && p.Length > 0)
{
m.Parameters.AddRange(p);
}
using (MySqlDataAdapter a = new MySqlDataAdapter(m))
{
a.Fill(t);
}
}
}
return t;
}
private void LoginClick(object sender, RoutedEventArgs e)
{
if (string.IsNullOrWhiteSpace(tbLogin.Text) || string.IsNullOrWhiteSpace(pbPassword.Password))
{
tbMsg.Text = "Введите логин и пароль";
return;
}
try
{
DataTable t = Q(
@"select u.UserID, u.FullName, r.RoleName
from Users u
join Roles r on r.RoleID = u.RoleID
where u.Login = @l and u.PasswordHash = @p",
new MySqlParameter("@l", tbLogin.Text.Trim()),
new MySqlParameter("@p", pbPassword.Password.Trim())
);
if (t.Rows.Count == 0)
{
tbMsg.Text = "Неверный логин или пароль";
return;
}
DataRow row = t.Rows[0];
int userId = Convert.ToInt32(row["UserID"]);
string fullName = Convert.ToString(row["FullName"]);
string roleName = Convert.ToString(row["RoleName"]);
MainWindow w = new MainWindow(userId, fullName, roleName);
w.Show();
Close();
}
catch (Exception ex)
{
tbMsg.Text = ex.Message;
}
}
}
}
⸻
5. MainWindow.xaml
<Window x:Class="LabApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Учет лабораторных анализов" Height="700" Width="1200" WindowStartupLocation="CenterScreen">
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border BorderBrush="Gray" BorderThickness="1" Padding="10" Margin="0,0,0,10">
<DockPanel>
<StackPanel Orientation="Horizontal" DockPanel.Dock="Left">
<TextBlock Text="Пользователь: " FontWeight="Bold"/>
<TextBlock x:Name="tbUser" Margin="0,0,20,0"/>
<TextBlock Text="Роль: " FontWeight="Bold"/>
<TextBlock x:Name="tbRole"/>
</StackPanel>
<Button Content="Выйти" Width="100" Height="30" DockPanel.Dock="Right" Click="ExitClick"/>
</DockPanel>
</Border>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TabControl Margin="0,0,10,0">
<TabItem Header="Пациенты">
<DataGrid x:Name="dgPatients" IsReadOnly="True" CanUserAddRows="False"/>
</TabItem>
<TabItem Header="Исследования">
<DataGrid x:Name="dgTests" IsReadOnly="True" CanUserAddRows="False"/>
</TabItem>
</TabControl>
<StackPanel Grid.Column="1">
<TextBlock Text="Пациент"/>
<ComboBox x:Name="cbPatients" Margin="0,5,0,10"/>
<TextBlock Text="Тип анализа"/>
<ComboBox x:Name="cbAnalysis" Margin="0,5,0,10"/>
<TextBlock Text="Результат"/>
<TextBox x:Name="tbResult" Height="30" Margin="0,5,0,10"/>
<TextBlock Text="Комментарий"/>
<TextBox x:Name="tbComment"
Height="100"
Margin="0,5,0,10"
AcceptsReturn="True"
TextWrapping="Wrap"/>
<Button Content="Добавить исследование" Height="35" Margin="0,0,0,10" Click="AddTest"/>
<TextBlock x:Name="tbMsg" TextWrapping="Wrap"/>
</StackPanel>
</Grid>
</Grid>
</Window>
⸻
6. MainWindow.xaml.cs
using System;
using System.Data;
using System.Windows;
using MySqlConnector;
namespace LabApp
{
public partial class MainWindow : Window
{
private string cs = "Server=localhost;Port=3306;Database=lab_accounting_db;Uid=root;Pwd=12345;";
private int currentUserId;
private string currentFullName;
private string currentRoleName;
public MainWindow(int userId, string fullName, string roleName)
{
InitializeComponent();
currentUserId = userId;
currentFullName = fullName;
currentRoleName = roleName;
tbUser.Text = currentFullName;
tbRole.Text = currentRoleName;
LoadData();
}
private DataTable Q(string sql, params MySqlParameter[] p)
{
DataTable t = new DataTable();
using (MySqlConnection c = new MySqlConnection(cs))
{
using (MySqlCommand m = new MySqlCommand(sql, c))
{
if (p != null && p.Length > 0)
{
m.Parameters.AddRange(p);
}
using (MySqlDataAdapter a = new MySqlDataAdapter(m))
{
a.Fill(t);
}
}
}
return t;
}
private void X(string sql, params MySqlParameter[] p)
{
using (MySqlConnection c = new MySqlConnection(cs))
{
c.Open();
using (MySqlCommand m = new MySqlCommand(sql, c))
{
if (p != null && p.Length > 0)
{
m.Parameters.AddRange(p);
}
m.ExecuteNonQuery();
}
}
}
private void LoadData()
{
try
{
dgPatients.ItemsSource = Q(
@"select
PatientID 'ID',
LastName 'Фамилия',
FirstName 'Имя',
MiddleName 'Отчество',
date_format(BirthDate, '%d.%m.%Y') 'Дата рождения',
Gender 'Пол',
Phone 'Телефон'
from Patients
order by LastName, FirstName, MiddleName"
).DefaultView;
dgTests.ItemsSource = Q(
@"select
lt.LabTestID 'ID',
concat(p.LastName, ' ', p.FirstName, ' ', ifnull(p.MiddleName,'')) 'Пациент',
at.AnalysisName 'Анализ',
lt.ResultValue 'Результат',
at.Unit 'Ед.изм.',
at.ReferenceRange 'Норма',
date_format(lt.TestDate, '%d.%m.%Y %H:%i') 'Дата',
u.FullName 'Лаборант',
lt.CommentText 'Комментарий'
from LabTests lt
join Patients p on p.PatientID = lt.PatientID
join AnalysisTypes at on at.AnalysisTypeID = lt.AnalysisTypeID
join Users u on u.UserID = lt.UserID
order by lt.TestDate desc"
).DefaultView;
cbPatients.ItemsSource = Q(
@"select
PatientID,
concat(LastName, ' ', FirstName, ' ', ifnull(MiddleName,''), ' [', date_format(BirthDate, '%d.%m.%Y'), ']') as FullInfo
from Patients
order by LastName, FirstName, MiddleName"
).DefaultView;
cbAnalysis.ItemsSource = Q(
@"select
AnalysisTypeID,
concat(AnalysisName, ' (', Unit, ', норма: ', ReferenceRange, ')') as FullInfo
from AnalysisTypes
order by AnalysisName"
).DefaultView;
cbPatients.DisplayMemberPath = "FullInfo";
cbPatients.SelectedValuePath = "PatientID";
cbAnalysis.DisplayMemberPath = "FullInfo";
cbAnalysis.SelectedValuePath = "AnalysisTypeID";
if (cbPatients.Items.Count > 0)
{
cbPatients.SelectedIndex = 0;
}
if (cbAnalysis.Items.Count > 0)
{
cbAnalysis.SelectedIndex = 0;
}
tbResult.Clear();
tbComment.Clear();
tbMsg.Text = "";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void AddTest(object sender, RoutedEventArgs e)
{
decimal result;
object commentValue;
if (cbPatients.SelectedValue == null)
{
tbMsg.Text = "Выберите пациента";
return;
}
if (cbAnalysis.SelectedValue == null)
{
tbMsg.Text = "Выберите анализ";
return;
}
if (string.IsNullOrWhiteSpace(tbResult.Text))
{
tbMsg.Text = "Введите результат";
return;
}
if (!decimal.TryParse(tbResult.Text.Trim().Replace('.', ','), out result))
{
tbMsg.Text = "Результат должен быть числом";
return;
}
if (string.IsNullOrWhiteSpace(tbComment.Text))
{
commentValue = DBNull.Value;
}
else
{
commentValue = tbComment.Text.Trim();
}
try
{
X(
@"insert into LabTests
(PatientID, AnalysisTypeID, UserID, TestDate, ResultValue, CommentText)
values
(@p, @a, @u, now(), @r, @c)",
new MySqlParameter("@p", cbPatients.SelectedValue),
new MySqlParameter("@a", cbAnalysis.SelectedValue),
new MySqlParameter("@u", currentUserId),
new MySqlParameter("@r", result),
new MySqlParameter("@c", commentValue)
);
tbResult.Clear();
tbComment.Clear();
tbMsg.Text = "Данные успешно добавлены";
dgTests.ItemsSource = Q(
@"select
lt.LabTestID 'ID',
concat(p.LastName, ' ', p.FirstName, ' ', ifnull(p.MiddleName,'')) 'Пациент',
at.AnalysisName 'Анализ',
lt.ResultValue 'Результат',
at.Unit 'Ед.изм.',
at.ReferenceRange 'Норма',
date_format(lt.TestDate, '%d.%m.%Y %H:%i') 'Дата',
u.FullName 'Лаборант',
lt.CommentText 'Комментарий'
from LabTests lt
join Patients p on p.PatientID = lt.PatientID
join AnalysisTypes at on at.AnalysisTypeID = lt.AnalysisTypeID
join Users u on u.UserID = lt.UserID
order by lt.TestDate desc"
).DefaultView;
}
catch (Exception ex)
{
tbMsg.Text = ex.Message;
}
}
private void ExitClick(object sender, RoutedEventArgs e)
{
LoginWindow w = new LoginWindow();
w.Show();
Close();
}
}
}
⸻
7. Что именно я поменял под C# 7.3
Убрал конструкции, которые часто ломаются на старой версии:
• using var ...
• сокращённый new("@x", value)
Заменил на обычный стиль:
using (MySqlConnection c = new MySqlConnection(cs))
{
}
и
new MySqlParameter("@x", value)
⸻
8. Что не забудь поменять
Во всех .cs файлах укажи свой пароль:
private string cs = "Server=localhost;Port=3306;Database=lab_accounting_db;Uid=root;Pwd=12345;";
⸻
9. Если хочешь, я следующим сообщением так же полностью перепишу под C# 7.3 и сам SQL-скрипт с красивыми именами таблиц/полей для отчёта, либо сделаю сразу готовый вариант проекта с разграничением по ролям.