1 2 3 4 5 6 |
System.Threading.Timer _timer = new System.Threading.Timer(x => { Invoke(new Action(() => { xxx(); })); }); textBox1.TextChanged += (s, e) => { _timer.Change(500, Timeout.Infinite); }; |
自分用のメモです。内容が間違っていたり、作りかけで動作しないコードなどあるのでご注意ください。
1 2 3 4 5 6 |
System.Threading.Timer _timer = new System.Threading.Timer(x => { Invoke(new Action(() => { xxx(); })); }); textBox1.TextChanged += (s, e) => { _timer.Change(500, Timeout.Infinite); }; |
LAN経由で現場のディスプレイに資料を表示させておくアイデアの検証用。
何かしらのスクリプトで資料のファイルを自動で開く方法も考えたけど、資料を準備する側が画像に変換する手間をかけれるならプログラムが簡単で済む。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
using System; using System.Drawing; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); var timer = new Timer(); timer.Tick += (s, e) => { DisplayImage(); }; timer.Interval = 1000 * 60 * 15; // 15分 timer.Start(); this.Resize += (s, e) => { var w = this.Width - 50; var h = this.Height - 70; pictureBox1.Left = 10; pictureBox1.Top = 10; pictureBox1.Width = w / 2; pictureBox1.Height = h / 2; pictureBox2.Left = w / 2 + 20; pictureBox2.Top = 10; pictureBox2.Width = w / 2; pictureBox2.Height = h / 2; pictureBox3.Left = 10; pictureBox3.Top = h / 2 + 20; pictureBox3.Width = w / 2; pictureBox3.Height = h / 2; pictureBox4.Left = w / 2 + 20; pictureBox4.Top = h / 2 + 20; pictureBox4.Width = w / 2; pictureBox4.Height = h / 2; }; pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; pictureBox2.SizeMode = PictureBoxSizeMode.Zoom; pictureBox3.SizeMode = PictureBoxSizeMode.Zoom; pictureBox4.SizeMode = PictureBoxSizeMode.Zoom; pictureBox1.BorderStyle = BorderStyle.FixedSingle; pictureBox2.BorderStyle = BorderStyle.FixedSingle; pictureBox3.BorderStyle = BorderStyle.FixedSingle; pictureBox4.BorderStyle = BorderStyle.FixedSingle; pictureBox1.BackColor = Color.White; pictureBox2.BackColor = Color.White; pictureBox3.BackColor = Color.White; pictureBox4.BackColor = Color.White; this.WindowState = FormWindowState.Maximized; DisplayImage(); } private void DisplayImage() { string dir = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + @"\image\"; pictureBox1.ImageLocation = dir + "1.jpg"; pictureBox2.ImageLocation = dir + "2.jpg"; pictureBox3.ImageLocation = dir + "3.jpg"; pictureBox4.ImageLocation = dir + "4.jpg"; Text = DateTime.Now.ToString("工場掲示板 MM月dd日HH時mm分") + " 更新"; } } } |
WindowsFormsばかりでASP.NETで動くものを作ったことがなかったので、勉強を兼ねて機器管理アプリを作ってみた。
Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.EntityFrameworkCore; using System.Reflection; using WebApplication1.Models; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); builder.Services.AddDbContext<TestDbContext>(options => { options.UseSqlite("Data Source=" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\dat.sqlite"); }); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/account/login/"; }); builder.Services.AddControllers(options => { options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build())); }); builder.Services.AddSingleton<SelectItems>(); var app = builder.Build(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseAuthentication(); app.MapControllerRoute( name: "default", pattern: "{controller=TestTable33}/{action=Index}/{id?}"); app.Run(); |
ApplicationUser.cs
1 2 3 4 5 6 7 8 9 10 11 12 |
using System.ComponentModel.DataAnnotations; namespace WebApplication1 { public class ApplicationUser { public string UserName { get; set; } [Required(ErrorMessage = "パスワードは必須です。")] public string Password { get; set; } } } |
Index.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
@model IEnumerable<WebApplication1.Models.TestTable33> <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> @if (User.Identity.Name == "管理ユーザー") { <a class="d-grid btn btn-primary bg-gradient mt-1" asp-action="Create">新規作成</a> } else { <a class="d-grid btn btn-primary bg-gradient mt-1 disabled" asp-action="Create">新規作成</a> } </div> <div class="col-md-4 btn-group"> <a class="d-grid btn btn-primary bg-gradient mt-1" data-bs-toggle="collapse" data-bs-target="#searchMenu">検 索</a> <a class="d-grid btn btn-primary bg-gradient mt-1" asp-action="Index">クリア</a> </div> </div> </div> <form asp-action="search"> <div class="row"> <div class="col-12 collapse" id="searchMenu"> <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <input type="text" name="Number" class="form-control mt-1" placeholder="管理番号" /> </div> <div class="col-md-4"> <input type="text" name="Name" class="form-control mt-1" placeholder="一般名称" /> </div> <div class="col-md-4"> <input type="text" name="Model" class="form-control mt-1" placeholder="モデル名" /> </div> </div> <div class="row"> <div class="col-md-4"> <input type="text" name="Maker" class="form-control mt-1" placeholder="メーカー" /> </div> <div class="col-md-4"> <input type="text" name="Location" class="form-control mt-1" placeholder="設置場所" /> </div> <div class="col-md-4 text-end"> <input type="submit" value="実 行" class="btn btn-primary bg-gradient mt-1" /> </div> </div> </div> </div> </div> </form> <div class="row"> <div class="col-md-12"> <div class="card card-body bg-light border-dark table-responsive"> <div class="row"> <table class="table bg-white table-bordered border-dark table-hover"> <thead> <tr class="text-nowrap"> <th class="col-2"> 管理番号 </th> <th class="col-2"> 一般名称 </th> <th class="col-2"> モデル名 </th> <th class="col-2"> メーカー </th> <th class="col-2"> 設置場所 </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr class="text-break"> <td> @Html.DisplayFor(modelItem => item.管理番号) <br> <a class="btn btn-primary bg-gradient mt-1" asp-action="Details" asp-route-id="@item.Id">詳細</a> @if (User.Identity.Name == "管理ユーザー") { <a class="btn btn-primary bg-gradient mt-1" asp-action="Edit" asp-route-id="@item.Id">編集</a> <a class="btn btn-primary bg-gradient mt-1" asp-action="Delete" asp-route-id="@item.Id">削除</a> } else { <a class="btn btn-primary bg-gradient mt-1 disabled" asp-action="Edit" asp-route-id="@item.Id">編集</a> <a class="btn btn-primary bg-gradient mt-1 disabled" asp-action="Delete" asp-route-id="@item.Id">削除</a> } </td> <td> @Html.DisplayFor(modelItem => item.一般名称) </td> <td> @Html.DisplayFor(modelItem => item.モデル名) </td> <td> @Html.DisplayFor(modelItem => item.メーカー) </td> <td> @Html.DisplayFor(modelItem => item.設置保存場所) </td> </tr> } </tbody> </table> </div> </div> </div> </div> |
Edit.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
@model WebApplication1.Models.TestTable33 @inject WebApplication1.Models.SelectItems selectItems <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <a class="d-grid btn btn-primary bg-gradient" asp-action="Index">キャンセル</a> </div> </div> </div> <form enctype="multipart/form-data" asp-action="Edit"> <div class="card card-body bg-light border-dark"> <div class="row"> <div class="col-md-4"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <input type="hidden" asp-for="Id" /> <div class="form-group"> <label asp-for="管理番号" class="control-label"></label> <input asp-for="管理番号" class="form-control" /> <span asp-validation-for="管理番号" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="関連番号" class="control-label"></label> <input asp-for="関連番号" class="form-control" /> <span asp-validation-for="関連番号" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="導入年月" class="control-label"></label> <input asp-for="導入年月" class="form-control ymd" /> <span asp-validation-for="導入年月" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="担当者1" class="control-label"></label> <input asp-for="担当者1" class="form-control" /> <span asp-validation-for="担当者1" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="担当者2" class="control-label"></label> <input asp-for="担当者2" class="form-control" /> <span asp-validation-for="担当者2" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="一般名称" class="control-label"></label> <input asp-for="一般名称" class="form-control" /> <span asp-validation-for="一般名称" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="モデル名" class="control-label"></label> <input asp-for="モデル名" class="form-control" /> <span asp-validation-for="モデル名" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="メーカー" class="control-label"></label> <input asp-for="メーカー" class="form-control" /> <span asp-validation-for="メーカー" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="設置保存場所" class="control-label"></label> <input asp-for="設置保存場所" class="form-control" /> <span asp-validation-for="設置保存場所" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="所有形態" class="control-label"></label> <select asp-for="所有形態" asp-items="selectItems.AcquiredType" class="form-control"></select> <span asp-validation-for="所有形態" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Idユーザー名" class="control-label"></label> <input asp-for="Idユーザー名" class="form-control" /> <span asp-validation-for="Idユーザー名" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="メール" class="control-label"></label> <input asp-for="メール" class="form-control" /> <span asp-validation-for="メール" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード1" class="control-label">パスワード1(管理ユーザーのみ)</label> <input asp-for="パスワード1" class="form-control" /> <span asp-validation-for="パスワード1" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード2" class="control-label">パスワード2(管理ユーザーのみ)</label> <input asp-for="パスワード2" class="form-control" /> <span asp-validation-for="パスワード2" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード3" class="control-label">パスワード3(管理ユーザーのみ)</label> <input asp-for="パスワード3" class="form-control" /> <span asp-validation-for="パスワード3" class="text-danger"></span> </div> </div> <div class="col-md-4"> <div class="form-group"> <label class="control-label">写真</label> <div> @{ if ((bool)ViewData["exists"]) { <img src="@Url.Content("~/image/" + Model.Id + ".png")" class=img-fluid> } else { <img src="@Url.Content("~/image/nophoto.png")" class=img-fluid> } } </div> <input type="file" name="furniture" class="form-control" accept=".png,.jpg" /> </div> <div class="form-group"> <label asp-for="備考" class="control-label"></label> <textarea rows="20" asp-for="備考" class="form-control">@Model.備考</textarea> </div> <div class="row"> <div class="col-md-6"></div> <div class="col-md-6"> <div class="form-group"> <input type="submit" value="登 録" class="form-control btn btn-primary bg-gradient mt-1" /> </div> </div> </div> </div> </div> </div> </form> @section Scripts { @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } <script type="text/javascript"> window.addEventListener('load', function () { let elements = document.querySelectorAll('.ymd'); for (let i = 0; i < elements.length; i++) { elements[i].addEventListener('blur', function () { let ymd = new Date(elements[i].value); if (Number.isNaN(ymd.getTime())) { elements[i].value = ""; return; } let y = ymd.getFullYear(); if (y === 2001) y = new Date().getFullYear(); let m = ("00" + (ymd.getMonth() + 1)).slice(-2); let d = ("00" + ymd.getDate()).slice(-2); elements[i].value = y + "/" + m + "/" + d; }); } }); </script> } |
Details.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
@model WebApplication1.Models.TestTable33 <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <a class="d-grid btn btn-primary bg-gradient" asp-action="Index">キャンセル</a> </div> </div> </div> <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-12"> <img class="img-fluid" src=@Url.Content("/TestTable33/CreateImage/" + ViewData["number"])> </div> </div> </div> <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <div class="form-group"> <label asp-for="管理番号" class="control-label"></label> <input asp-for="管理番号" class="form-control" /> </div> <div class="form-group"> <label asp-for="関連番号" class="control-label"></label> <input asp-for="関連番号" class="form-control" /> </div> <div class="form-group"> <label asp-for="導入年月" class="control-label"></label> <input asp-for="導入年月" class="form-control ymd" /> </div> <div class="form-group"> <label asp-for="担当者1" class="control-label"></label> <input asp-for="担当者1" class="form-control" /> </div> <div class="form-group"> <label asp-for="担当者2" class="control-label"></label> <input asp-for="担当者2" class="form-control" /> </div> <div class="form-group"> <label asp-for="一般名称" class="control-label"></label> <input asp-for="一般名称" class="form-control" /> </div> <div class="form-group"> <label asp-for="モデル名" class="control-label"></label> <input asp-for="モデル名" class="form-control" /> </div> <div class="form-group"> <label asp-for="メーカー" class="control-label"></label> <input asp-for="メーカー" class="form-control" /> </div> <div class="form-group"> <label asp-for="設置保存場所" class="control-label"></label> <input asp-for="設置保存場所" class="form-control" /> </div> <div class="form-group"> <label asp-for="所有形態" class="control-label"></label> <input asp-for="所有形態" class="form-control" /> </div> <div class="form-group"> <label asp-for="Idユーザー名" class="control-label"></label> <input asp-for="Idユーザー名" class="form-control" /> </div> <div class="form-group"> <label asp-for="メール" class="control-label"></label> <input asp-for="メール" class="form-control" /> </div> <div class="form-group"> <label asp-for="パスワード1" class="control-label">パスワード1(管理ユーザーのみ)</label> <input asp-for="パスワード1" class="form-control" /> </div> <div class="form-group"> <label asp-for="パスワード2" class="control-label">パスワード2(管理ユーザーのみ)</label> <input asp-for="パスワード2" class="form-control" /> </div> <div class="form-group"> <label asp-for="パスワード3" class="control-label">パスワード3(管理ユーザーのみ)</label> <input asp-for="パスワード3" class="form-control" /> </div> </div> <div class="col-md-4"> <div class="form-group"> <label class="control-label">写真</label> <div> @{ if ((bool)ViewData["exists"]) { <img src="@Url.Content("~/image/" + Model.Id + ".png")" class=img-fluid> } else { <img src="@Url.Content("~/image/nophoto.png")" class=img-fluid> } } </div> </div> <div class="form-group"> <label asp-for="備考" class="control-label"></label> <textarea rows="20" asp-for="備考" class="form-control">@Model.備考</textarea> </div> </div> </div> </div> |
Delete.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@model WebApplication1.Models.TestTable33 <div class="card card-body bg-light border-dark mb-1"> <p>本当に削除しますか?</p> </div> <form asp-action="Delete"> <div class="card card-body bg-light border-dark"> <div class="row"> <div class="col-md-4"> <a class="d-grid btn btn-primary bg-gradient mt-1" asp-action="Index">キャンセル</a> </div> <div class="col-md-4"> <input type="submit" value="削 除" class="form-control btn btn-danger bg-gradient mt-1" /> <input type="hidden" asp-for="Id" /> </div> </div> </div> </form> |
Create.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
@model WebApplication1.Models.TestTable33 @inject WebApplication1.Models.SelectItems selectItems <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <a class="d-grid btn btn-primary bg-gradient" asp-action="Index">キャンセル</a> </div> </div> </div> <form enctype="multipart/form-data" asp-action="Create"> <div class="card card-body bg-light border-dark"> <div class="row"> <div class="col-md-4"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group d-none"> <label asp-for="Id" class="control-label"></label> <input asp-for="Id" class="form-control" /> <span asp-validation-for="Id" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="管理番号" class="control-label"></label> <input asp-for="管理番号" class="form-control" /> <span asp-validation-for="管理番号" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="関連番号" class="control-label"></label> <input asp-for="関連番号" class="form-control" /> <span asp-validation-for="関連番号" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="導入年月" class="control-label"></label> <input asp-for="導入年月" class="form-control ymd" /> <span asp-validation-for="導入年月" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="担当者1" class="control-label"></label> <input asp-for="担当者1" class="form-control" /> <span asp-validation-for="担当者1" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="担当者2" class="control-label"></label> <input asp-for="担当者2" class="form-control" /> <span asp-validation-for="担当者2" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="一般名称" class="control-label"></label> <input asp-for="一般名称" class="form-control" /> <span asp-validation-for="一般名称" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="モデル名" class="control-label"></label> <input asp-for="モデル名" class="form-control" /> <span asp-validation-for="モデル名" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="メーカー" class="control-label"></label> <input asp-for="メーカー" class="form-control" /> <span asp-validation-for="メーカー" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="設置保存場所" class="control-label"></label> <input asp-for="設置保存場所" class="form-control" /> <span asp-validation-for="設置保存場所" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="所有形態" class="control-label"></label> <select asp-for="所有形態" asp-items="selectItems.AcquiredType" class="form-control"></select> <span asp-validation-for="所有形態" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Idユーザー名" class="control-label"></label> <input asp-for="Idユーザー名" class="form-control" /> <span asp-validation-for="Idユーザー名" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="メール" class="control-label"></label> <input asp-for="メール" class="form-control" /> <span asp-validation-for="メール" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード1" class="control-label">パスワード1(管理ユーザーのみ)</label> <input asp-for="パスワード1" class="form-control" /> <span asp-validation-for="パスワード1" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード2" class="control-label">パスワード2(管理ユーザーのみ)</label> <input asp-for="パスワード2" class="form-control" /> <span asp-validation-for="パスワード2" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード3" class="control-label">パスワード3(管理ユーザーのみ)</label> <input asp-for="パスワード3" class="form-control" /> <span asp-validation-for="パスワード3" class="text-danger"></span> </div> </div> <div class="col-md-4"> <div class="form-group"> <label class="control-label">写真</label> <input type="file" name="furniture" class="form-control" accept=".png,.jpg"/> </div> <div class="form-group"> <label asp-for="備考" class="control-label"></label> <textarea rows="20" asp-for="備考" class="form-control"> @Model.備考 </textarea> </div> <div class="row"> <div class="col-md-6"></div> <div class="col-md-6"> <div class="form-group"> <input type="submit" value="登 録" class="form-control btn btn-primary bg-gradient mt-1" /> </div> </div> </div> </div> </div> </div> </form> @section Scripts { @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } <script type="text/javascript"> window.addEventListener('load', function () { let elements = document.querySelectorAll('.ymd'); for (let i = 0; i < elements.length; i++) { elements[i].addEventListener('blur', function () { let ymd = new Date(elements[i].value); if (Number.isNaN(ymd.getTime())) { elements[i].value = ""; return; } let y = ymd.getFullYear(); if (y === 2001) y = new Date().getFullYear(); let m = ("00" + (ymd.getMonth() + 1)).slice(-2); let d = ("00" + ymd.getDate()).slice(-2); elements[i].value = y + "/" + m + "/" + d; }); } }); </script> } |
_Layout.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>IT機器管理システム</title> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" /> <link rel="stylesheet" href="~/WebApplication1.styles.css" asp-append-version="true" /> </head> <body> @if (User.Identity.IsAuthenticated) { <div class="container"> <div class="row"> <div class="col-md-12"> <div class="card card-body bg-light border-dark mt-1 mb-1"> <div class="col-md-2"> <a class="form-control btn btn-danger bg-gradient" asp-controller="Account" asp-action="Logout">ログアウト</a> </div> </div> </div> </div> </div> } <div class="container"> <main role="main" class="pb-3"> @RenderBody() </main> </div> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @await RenderSectionAsync("Scripts", required: false) </body> </html> |
Login.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
@model ApplicationUser <div class="row"> <div class="col-md-4 mx-auto mt-4"> <form asp-controller="Account" asp-action="Login"> IT機器管理システム <div class="card card-body bg-light p-4 border-dark"> <div class="form-group"> ユーザー名 <select class="form-select" name="UserName"> <option value="管理ユーザー">管理ユーザー</option> <option value="閲覧ユーザー">閲覧ユーザー</option> </select> </div> <div class="form-group"> パスワード <input name="password" type="password" class="form-control" /> <span asp-validation-for="Password" class="text-danger"></span> </div> <div class="row"> <div class="col-md-6"></div> <div class="col-md-6"> <input name="submit" value="ログイン" type="submit" class="form-control btn btn-primary bg-gradient mt-1" /> </div> </div> <input type="hidden" name="returnUrl" value="@Model" /> </div> </form> </div> </div> |
TestTable33.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
namespace WebApplication1.Models { public partial class TestTable33 { public int Id { get; set; } public string? 管理番号 { get; set; } public string? 関連番号 { get; set; } public string? 導入年月 { get; set; } public string? 担当者1 { get; set; } public string? 担当者2 { get; set; } public string? 一般名称 { get; set; } public string? モデル名 { get; set; } public string? メーカー { get; set; } public string? 設置保存場所 { get; set; } public string? 所有形態 { get; set; } public string? Idユーザー名 { get; set; } public string? メール { get; set; } public string? パスワード { get; set; } public string? パスワード1 { get; set; } public string? パスワード2 { get; set; } public string? パスワード3 { get; set; } public string? 備考 { get; set; } } } |
PurchaseType.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
using Microsoft.AspNetCore.Mvc.Rendering; namespace WebApplication1.Models { public class SelectItems { public IEnumerable<SelectListItem> AcquiredType { get; } = new List<SelectListItem> { // Edit/所有形態 new SelectListItem {Text ="購入品", Value = "購入品"}, new SelectListItem {Text ="レンタル品", Value = "レンタル品"}, new SelectListItem {Text ="リース品(所有権移転)", Value = "リース品(所有権移転)"} }; } } |
TestTable33Controller.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using SkiaSharp; using WebApplication1.Models; using ZXing.SkiaSharp; namespace WebApplication1.Controllers { public class TestTable33Controller : Controller { private readonly TestDbContext _context; private readonly IWebHostEnvironment _environment; public TestTable33Controller(TestDbContext context, IWebHostEnvironment environment) { _context = context; _environment = environment; } public async Task<IActionResult> search(string Number, string Name, string Model, string Maker, string Location) { if (Number == null && Name == null && Model == null && Maker == null && Location == null) { return View("index", await _context.TestTable33s.ToListAsync()); } List<TestTable33> result = new List<TestTable33>(); if (Number != null) { var temp = await _context.TestTable33s.Where( m => m.管理番号.ToLower().Contains(Number.ToLower()) ).ToListAsync(); result.AddRange(temp); } if (Name != null) { var temp = await _context.TestTable33s.Where( m => m.一般名称.ToLower().Contains(Name.ToLower()) ).ToListAsync(); result.AddRange(temp); } if (Model != null) { var temp = await _context.TestTable33s.Where( m => m.モデル名.ToLower().Contains(Model.ToLower()) ).ToListAsync(); result.AddRange(temp); } if (Maker != null) { var temp = await _context.TestTable33s.Where( m => m.メーカー.ToLower().Contains(Maker.ToLower()) ).ToListAsync(); result.AddRange(temp); } if (Location != null) { var temp = await _context.TestTable33s.Where( m => m.設置保存場所.ToLower().Contains(Location.ToLower()) ).ToListAsync(); result.AddRange(temp); } return View("index", result.Distinct().OrderBy(m => m.Id)); } public async Task<IActionResult> Index() { return View(await _context.TestTable33s.ToListAsync()); } public async Task<IActionResult> CreateImage(string? id) { if (id == null) id = ""; var number = id; using SkiaSharp.SKBitmap bitmap = new SkiaSharp.SKBitmap(490, 100); using SkiaSharp.SKCanvas canvas = new SkiaSharp.SKCanvas(bitmap); canvas.Clear(SKColors.White); SkiaSharp.SKPaint paint1 = new SkiaSharp.SKPaint(); paint1.Style = SkiaSharp.SKPaintStyle.Fill; paint1.Color = SkiaSharp.SKColors.Blue; SkiaSharp.SKPaint paint2 = new SkiaSharp.SKPaint(); paint2.Style = SkiaSharp.SKPaintStyle.Fill; paint2.Color = SkiaSharp.SKColors.Black; paint2.TextSize = 36; paint2.Typeface = SkiaSharp.SKTypeface.FromFamilyName("Yu Gothic UI"); paint2.IsAntialias = true; canvas.DrawText("管理番号:", 110, 45, paint2); canvas.DrawText(number, 110, 85, paint2); ; var writer = new BarcodeWriter { Format = ZXing.BarcodeFormat.QR_CODE, Options = new ZXing.Common.EncodingOptions { Width = 90, Height = 90, Margin = 0, } }; var ms = new MemoryStream(); var qr = writer.Write(Request.Headers["Referer"]); canvas.DrawImage(SkiaSharp.SKImage.FromBitmap(qr), new SkiaSharp.SKPoint(5, 5)); bitmap.Encode(ms, SKEncodedImageFormat.Png, 100); ms.Position = 0; return new FileStreamResult(ms, "image/png"); } public async Task<IActionResult> Details(int? id) { if (id == null || _context.TestTable33s == null) { return RedirectToAction("Index", "TestTable33"); } var testTable33 = await _context.TestTable33s .FirstOrDefaultAsync(m => m.Id == id); if (testTable33 == null) { return NotFound(); } ViewData["number"] = testTable33.管理番号; if (User.Identity.Name == "閲覧ユーザー") { testTable33.パスワード1 = "*****"; testTable33.パスワード2 = "*****"; testTable33.パスワード3 = "*****"; } if(System.IO.File.Exists(_environment.WebRootPath + "/Image/" + id.ToString() + ".png")) { ViewData["exists"] = true; } else { ViewData["exists"] = false; } return View(testTable33); } public IActionResult Create() { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } var tableRow = _context.TestTable33s.OrderByDescending(m => m.Id).FirstOrDefault(); int maxId = 1; if (tableRow != null) maxId = tableRow.Id + 1; var testTable33 = new TestTable33(); testTable33.Id = maxId; testTable33.管理番号 = maxId.ToString().PadLeft(5, '0'); testTable33.備考 = "ログイン、ライセンス更新方法等"; return View(testTable33); } public async Task SaveImage(string id) { var formFile = Request.Form.Files["furniture"]; if (formFile != null) { using (var ms = new MemoryStream()) { await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap srcBitmap = SKBitmap.Decode(byteArray); ms.Position = 0; SKCodec codec = SKCodec.Create(ms); var origin = codec.EncodedOrigin; int w = srcBitmap.Width; int h = srcBitmap.Height; SKRect src; if (w > h) { int tmp = (w - h) / 2; src = new SKRect(tmp, 0, tmp + h, h); // left, top, right, bottom } else if (w < h) { int tmp = (h - w) / 2; src = new SKRect(0, tmp, w, tmp + w); } else // w == h { src = new SKRect(0, 0, w, h); } SKBitmap croppedBitmap = new SKBitmap(500, 500); SKCanvas canvas = new SKCanvas(croppedBitmap); // Exif Orientation switch (origin) { case SKEncodedOrigin.TopLeft: // 1 break; case SKEncodedOrigin.TopRight: // 2 canvas.Scale(-1, 1, 250, 250); break; case SKEncodedOrigin.BottomRight: // 3 canvas.RotateDegrees(180, 250, 250); break; case SKEncodedOrigin.BottomLeft: // 4 canvas.Scale(1, -1, 250, 250); break; case SKEncodedOrigin.LeftTop: // 5 canvas.RotateDegrees(90, 250, 250); canvas.Scale(1, -1, 250, 250); break; case SKEncodedOrigin.RightTop: // 6 canvas.RotateDegrees(90, 250, 250); break; case SKEncodedOrigin.RightBottom: // 7 canvas.RotateDegrees(90, 250, 250); canvas.Scale(-1, 1, 250, 250); break; case SKEncodedOrigin.LeftBottom: // 8 canvas.RotateDegrees(270, 250, 250); break; } SKRect dst = new SKRect(0, 0, 500, 500); canvas.DrawBitmap(srcBitmap, src, dst); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + id + ".png", FileMode.Create); croppedBitmap.Encode(fs, SKEncodedImageFormat.Png, 100); } } } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("Id,管理番号,関連番号,導入年月,担当者1,担当者2,一般名称,モデル名,メーカー,設置保存場所,所有形態,Idユーザー名,メール,パスワード,パスワード1,パスワード2,パスワード3,備考")] TestTable33 testTable33) { await SaveImage(testTable33.Id.ToString()); if (ModelState.IsValid) { _context.Add(testTable33); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } return View(testTable33); } public async Task<IActionResult> Edit(int? id) { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } if (id == null || _context.TestTable33s == null) { return NotFound(); } var testTable33 = await _context.TestTable33s.FindAsync(id); if (testTable33 == null) { return NotFound(); } if (System.IO.File.Exists(_environment.WebRootPath + "/Image/" + id.ToString() + ".png")) { ViewData["exists"] = true; } else { ViewData["exists"] = false; } return View(testTable33); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(int id, [Bind("Id,管理番号,関連番号,導入年月,担当者1,担当者2,一般名称,モデル名,メーカー,設置保存場所,所有形態,Idユーザー名,メール,パスワード,パスワード1,パスワード2,パスワード3,備考")] TestTable33 testTable33) { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } if (id != testTable33.Id) { return NotFound(); } await SaveImage(testTable33.Id.ToString()); if (ModelState.IsValid) { try { _context.Update(testTable33); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!TestTable33Exists(testTable33.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } return View(testTable33); } public async Task<IActionResult> Delete(int? id) { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } if (id == null || _context.TestTable33s == null) { return NotFound(); } var testTable33 = await _context.TestTable33s .FirstOrDefaultAsync(m => m.Id == id); if (testTable33 == null) { return NotFound(); } return View(testTable33); } [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<IActionResult> DeleteConfirmed(int id) { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } if (_context.TestTable33s == null) { return Problem("Entity set 'TestDbContext.TestTable33s' is null."); } string imagePath = _environment.WebRootPath + "/Image/" + id.ToString() + ".png"; if (System.IO.File.Exists(imagePath)) System.IO.File.Delete(imagePath); var testTable33 = await _context.TestTable33s.FindAsync(id); if (testTable33 != null) { _context.TestTable33s.Remove(testTable33); } await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } private bool TestTable33Exists(int id) { return _context.TestTable33s.Any(e => e.Id == id); } } } |
AccountController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace WebApplication1.Controllers { public class AccountController : Controller { List<ApplicationUser> users = new List<ApplicationUser> { new ApplicationUser{UserName = "管理ユーザー", Password = "abc"}, new ApplicationUser{UserName = "閲覧ユーザー", Password = "abc"} }; [AllowAnonymous] public IActionResult Login() { if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "TestTable33"); } return View(); } [HttpPost] [AutoValidateAntiforgeryToken] [AllowAnonymous] public async Task<IActionResult> Login(ApplicationUser user, string returnUrl = null) { if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "TestTable33"); } var lookupUser = users.Where(u => u.UserName == user.UserName).FirstOrDefault(); if (lookupUser?.Password != user.Password) { return View(user); } var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme); identity.AddClaim(new Claim(ClaimTypes.Name, lookupUser.UserName)); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity)); return RedirectToAction("Index", "TestTable33"); } public async Task<IActionResult> Logout() { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return RedirectToAction("Login"); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
var formFile = Request.Form.Files["furniture"]; if (formFile != null) { using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - FileStream // コンコードしていないのでBmp読込/書出可能 await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); string extension = System.IO.Path.GetExtension(formFile.FileName); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "1_" + testTable33.Id.ToString() + extension, FileMode.Create); //同名ファイルがあると上書きされる await fs.WriteAsync(byteArray, 0, byteArray.Length); } using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - SKImage - Encode(png) - FileStream // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKImage image = SkiaSharp.SKImage.FromEncodedData(byteArray); var data = image.Encode(SKEncodedImageFormat.Png, 100); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "2_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる data.SaveTo(fs); } using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - SKBitmap - Encode(png) - FileStream // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap bitmap = SKBitmap.Decode(byteArray); var data = bitmap.Encode(SKEncodedImageFormat.Png, 100); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "3_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる data.SaveTo(fs); } using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - SKBitmap - Encode(png) - FileStream // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap bitmap = SKBitmap.Decode(byteArray); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "4_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる bitmap.Encode(fs,SKEncodedImageFormat.Png, 100); // SKBitmapの場合StreamをTargetにできる } using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - SKBitmap - Encode(png) - MemoryStream - FileStream // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap bitmap = SKBitmap.Decode(byteArray); using (var ms2 = new MemoryStream()) { bitmap.Encode(ms2, SKEncodedImageFormat.Png, 100); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "5_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる await fs.WriteAsync(ms2.ToArray()); } } using (var ms = new MemoryStream()) { // IFormFile - MemoryStream - Byte[] - SKBitmap - SKCanvas - Encode(png) - FileStream // 500*500に切り抜き // Exif情報で回転 // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap srcBitmap = SKBitmap.Decode(byteArray); int w = srcBitmap.Width; int h = srcBitmap.Height; SKRect src; if (w > h) { int tmp = (w - h) / 2; src = new SKRect(tmp, 0, tmp+h, h); // left, top, right, bottom } else if(w < h) { int tmp = (h - w) / 2; src = new SKRect(0, tmp, w, tmp + w); } else // w == h { src = new SKRect(0,0,w,h); } SKBitmap croppedBitmap = new SKBitmap(500, 500); SKCanvas canvas = new SKCanvas(croppedBitmap); // Exif Orientation switch (origin) { case SKEncodedOrigin.TopLeft: // 1 break; case SKEncodedOrigin.TopRight: // 2 canvas.Scale(-1, 1, 250, 250); break; case SKEncodedOrigin.BottomRight: // 3 canvas.RotateDegrees(180, 250, 250); break; case SKEncodedOrigin.BottomLeft: // 4 canvas.Scale(1, -1, 250, 250); break; case SKEncodedOrigin.LeftTop: // 5 canvas.RotateDegrees(90, 250, 250); canvas.Scale(1, -1, 250, 250); break; case SKEncodedOrigin.RightTop: // 6 canvas.RotateDegrees(90, 250, 250); break; case SKEncodedOrigin.RightBottom: // 7 canvas.RotateDegrees(90, 250, 250); canvas.Scale(-1, 1, 250, 250); break; case SKEncodedOrigin.LeftBottom: // 8 canvas.RotateDegrees(270, 250, 250); break; } SKRect dst = new SKRect(0, 0, 500, 500); canvas.DrawBitmap(srcBitmap, src, dst); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "6_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる croppedBitmap.Encode(fs, SKEncodedImageFormat.Png, 100); // SKBitmapの場合StreamをTargetにできる } } |
●SDK
.NET Runtime、.NET Desktop Runtime、ASP.NET Core Runtimeが含まれる
●.NET Runtime
コンソールの実行に必要なコンポーネントのみ。
通常、この代わりに.NET Desktop Runtimeと ASP.NET Core Runtimeの両方をインストールする。
●.NET Desktop Runtime
WPF、Windows Formsをサポート。
Windowsに付属する.NET Frameworkとは異なる。
.NET Runtimeが含まれる。
ASP.NET Core Runtimeは含まれない。
●ASP.NET Core Runtime
.NET Runtimeをインストールする必要がある。
.NET Framework
https://learn.microsoft.com/ja-jp/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
.NET 5 以降
https://learn.microsoft.com/ja-jp/dotnet/core/install/how-to-detect-installed-versions?pivots=os-windows
.NET Framwork1.0(1.0)
.NET Framwork1.1(1.1)
.NET Framwork3.5(2.0, 3.0, 3.5)
.NET Framwork4.8(4, 4,5, 4.6, 4.7, 4.8)
.NET Core2.2(2.0, 2.1, 2.2)
.NET Core3.1(3.0, 3.1)
.NET5(5)
.NET6(6)
.NET Framwork3.5(2028年)
.NET Framwork4.8(2031年)
.NET Core3.1(2022年)
.NET5(2022年)
.NET6(2024年)
.NET5でFramworkとCoreが統合された
もともと複数のエクセルに分割されたデータで、都度ファイルを開いて検索+合計の計算を繰り返していたようなので、テキストファイル(CSV)にまとめ、インクリメンタルサーチで行の絞り込み+選択した行の合計を求める機能を作成した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Threading; using System.Windows.Forms; namespace 手入力工数検索 { public partial class Form1 : Form { string CsvPath = Application.StartupPath + @"\dat.csv"; List<string> RawItems = new List<string>(); int VisibleCount = 5000; string SearchWords = ""; object LockObject = new object(); bool CanExit = true; public Form1() { InitializeComponent(); RawItems = File.ReadAllLines(CsvPath).ToList(); var delayExecute = new DelayExecute(); delayExecute.Execute += (s, e) => UpdateDatasource(); textBox1.TextChanged += (s, e) => { lock (LockObject) { CanExit = false; } SearchWords = textBox1.Text; delayExecute.ReserveExecute(); }; listBox1.SelectedValueChanged += (s, e) => { decimal total = 0; foreach(var item in listBox1.SelectedItems) { var cols = item.ToString().Split(','); decimal.TryParse(cols[5], out decimal parseResult); total += parseResult; } label2.Text = "作業時間合計(選択行):" + total.ToString("0.00"); }; this.FormClosing += (s, e) => { lock (LockObject) { if (!CanExit) e.Cancel = true; } }; } private void UpdateDatasource() { IEnumerable<string> items = new List<string>(); if (SearchWords == "") { items = RawItems.Take(VisibleCount); } else { List<string> tmpList = new List<string>(RawItems); foreach (string tmpString in SearchWords.Split('|')) { tmpList = tmpList.AsParallel().Where(x => x.ToLower().Contains(tmpString.ToLower())).ToList(); } items = tmpList.Take(VisibleCount); } Invoke(new Action(() => { listBox1.DataSource = items.ToList(); })); lock (LockObject) { CanExit = true; } } } class DelayExecute { public event EventHandler Execute; private int DelayTime = 500; System.Threading.Timer Timer; public DelayExecute() { Timer = new System.Threading.Timer(x => { Execute(this, EventArgs.Empty); }); } public void ReserveExecute() { Timer.Change(DelayTime, Timeout.Infinite); } } } |
DataGridView版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Threading; using System.Windows.Forms; namespace 手入力工数検索 { public partial class Form1 : Form { string CsvPath = Application.StartupPath + @"\dat.csv"; List<string> RawItems = new List<string>(); int VisibleCount = 1000; string SearchWords = ""; object LockObject = new object(); bool CanExit = true; public Form1() { InitializeComponent(); RawItems = File.ReadAllLines(CsvPath).ToList(); var delayExecute = new DelayExecute(); delayExecute.Execute += (s, e) => UpdateDatasource(); textBox1.TextChanged += (s, e) => { lock (LockObject) { CanExit = false; } SearchWords = textBox1.Text; delayExecute.ReserveExecute(); }; dataGridView1.SelectionChanged += (s, e) => { decimal total = 0; foreach (DataGridViewRow row in dataGridView1.SelectedRows) { decimal.TryParse(row.Cells["作業時間"].Value.ToString(), out decimal parseResult); total += parseResult; } label2.Text = "作業時間合計(選択行):" + total.ToString("0.00"); }; this.FormClosing += (s, e) => { lock (LockObject) { if (!CanExit) e.Cancel = true; } }; SetDgv(); } private void SetDgv() { dataGridView1.RowHeadersWidth = 50; dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dataGridView1.ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False; dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; dataGridView1.Font = new Font("メイリオ", 10); dataGridView1.RowTemplate.Height = 22; dataGridView1.AllowUserToAddRows = false; dataGridView1.ReadOnly = true; typeof(DataGridView). GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic). SetValue(dataGridView1, true, null); } private void UpdateDatasource() { IEnumerable<string> items = new List<string>(); if (SearchWords == "") { items = RawItems.Take(VisibleCount); } else { List<string> tmpList = new List<string>(RawItems); foreach (string tmpString in SearchWords.Split('|')) { tmpList = tmpList.AsParallel().Where(x => x.ToLower().Contains(tmpString.ToLower())).ToList(); } items = tmpList.Take(VisibleCount); } DataSet ds = new DataSet(); DataTable dt = new DataTable("tbl"); ds.Tables.Add(dt); string[] cols = new string[] { "作業者","型式","数量","工番","作業日","作業時間","備考","登録日時" }; foreach (string c in cols) { dt.Columns.Add(c); } foreach(string item in items) { DataRow row = dt.NewRow(); string[] vals = item.Split(','); row["作業者"] = vals[0]; row["型式"] = vals[1]; row["数量"] = vals[2]; row["工番"] = vals[3]; row["作業日"] = vals[4]; row["作業時間"] = vals[5]; row["備考"] = vals[6]; row["登録日時"] = vals[7]; ds.Tables["tbl"].Rows.Add(row); } Invoke(new Action(() => { dataGridView1.DataSource = ds.Tables["tbl"]; dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); })); lock (LockObject) { CanExit = true; } } } class DelayExecute { public event EventHandler Execute; private int DelayTime = 800; System.Threading.Timer Timer; public DelayExecute() { Timer = new System.Threading.Timer(x => { Execute(this, EventArgs.Empty); }); } public void ReserveExecute() { Timer.Change(DelayTime, Timeout.Infinite); } } } |
・勤続年数
特に定めのない計算の場合、端数処理には裁量がある。
年の期間を求める場合、一般的には一年未満の端数を切上げ(1年+1日でも2年)とすることが多く、同じように月の期間を求める場合は、1ヶ月未満の日の端数も切上げて1ヶ月とすることが多い。
https://www.nta.go.jp/taxes/shiraberu/taxanswer/shotoku/1420.htm
ただ、日の端数を切上げたことにより1年を超えてしまい2年になるというような考え方はせず「1年未満の端数は1年に切上げる」だけと考えることが普通。
月の部分については、切上げ(1日でも所属したら1ヶ月とする)以外にも、日付を無視する計算方法もある。
イメージとして切上げは開始月を月初に、終了月を月末にしていて、日付無視は開始月と終了月を同じ日にしていると考えると分かりやすい。
・年齢
年齢の何ヶ月の部分は月末をどうするかが難しい。シンプルなのは先ず、
経過月 = 終了月-開始月
で経過月を算出し、
終了月の日 = 月末 OR 開始月の日 <= 終了月の日
満たさない場合、経過月-1月
という計算式。あるいは、
終了月の日 != 月末 AND 開始月の日 > 終了月の日
満たす場合、経過月-1月
開始月の日 <= 終了月の日
という部分は普通の考え方で、
終了月の日 = 月末
という部分は、開始月、終了月が月末の場合、1/31~2/28など最初の条件を満たさなくても、1ヶ月プラスされる部分があり、この場合、開始月側は何日であっても問題ないので終了月側だけ月末かどうか判断している。
ただ、月末同士で1ヶ月と考える方が自然ではあるけど、当然、
7/31-8/30で1ヶ月判定なし
8/31-9/30で1ヶ月判定あり
というよう結果もあるので少し気持ち悪さも残る。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
using System; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); textBox1.LostFocus += DateParse; textBox2.LostFocus += DateParse; } private void DateParse(object sender, EventArgs e) { TextBox textBox = (TextBox)sender; try { textBox.Text = DateTime.Parse(textBox.Text).ToString("yyyy/MM/dd"); } catch { textBox.Text = ""; } GetDuration(); } private void GetDuration() { if (textBox1.Text == "" || textBox2.Text == "") return; var startDate = DateTime.Parse(textBox1.Text); var endDate = DateTime.Parse(textBox2.Text); if (startDate > endDate) return; int y = endDate.Year - startDate.Year; int m = endDate.Month - startDate.Month; if (startDate.Month > endDate.Month) { y = y - 1; m = 12 + m; // mはマイナスの値が入っている } // 勤続年数(切上げ) -------------------------------------------------------- int yy = y; int mm = m + 1; if (mm == 12) // mmは最大でもm=11で+1され12まで { yy = y + 1; mm = 0; } textBox3.Text = yy.ToString() + "年" + mm.ToString() + "ヶ月"; // 勤続年数(切下げ) -------------------------------------------------------- textBox4.Text = y.ToString() + "年" + m.ToString() + "ヶ月"; // 年齢 -------------------------------------------------------- bool isLastDay = false; if (endDate.Month != endDate.AddDays(1).Month) isLastDay = true; // 月末かどうか int yyy = y; int mmm = m; if (startDate.Day > endDate.Day && !isLastDay) mmm = m - 1; if (mmm == -1) // mmmは最低でもm=0で-1され-1まで { yyy = y - 1; mmm = 11; } textBox5.Text = yyy.ToString() + "年" + mmm.ToString() + "ヶ月"; } } } |
・当年度末の勤続年数/年齢
時々出てくる当年度というのはだいたい4月~3月の期間で、会社によって締日が月末ではない場合もあり、例えば20日締の場合など3/21~3/20のようになったりする。先ず、現在の年の3月20日として、もし現在が3月20日以降の場合、現在の年に+1年の3月20日にする。
ちなみに年度末が12/31を指す場合は、現在の年の12月31日とすればいいので特に計算する必要はない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
using System; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); textBox1.LostFocus += DateParse; textBox2.LostFocus += DateParse; } private void DateParse(object sender, EventArgs e) { TextBox textBox = (TextBox)sender; try { textBox.Text = DateTime.Parse(textBox.Text).ToString("yyyy/MM/dd"); } catch { textBox.Text = ""; } GetDuration(); } private DateTime GetYearEnd(DateTime target) { var yearEnd = new DateTime(target.Year, 3, 20); if (target > yearEnd) yearEnd = yearEnd.AddYears(1); return yearEnd; } private void GetDuration() { if (textBox1.Text == "" || textBox2.Text == "") return; var startDate = DateTime.Parse(textBox1.Text); var endDate = DateTime.Parse(textBox2.Text); endDate = GetYearEnd(endDate); // 年度末 if (startDate > endDate) return; int y = endDate.Year - startDate.Year; int m = endDate.Month - startDate.Month; if (startDate.Month > endDate.Month) { y = y - 1; m = 12 + m; // mはマイナスの値が入っている } bool isLastDay = false; if (endDate.Month != endDate.AddDays(1).Month) isLastDay = true; // 月末かどうか int yyy = y; int mmm = m; if (startDate.Day > endDate.Day && !isLastDay) mmm = m - 1; if (mmm == -1) // mmmは最低でもm=0で-1され-1まで { yyy = y - 1; mmm = 11; } textBox3.Text = yyy.ToString() + "年" + mmm.ToString() + "ヶ月"; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Security.Cryptography; using System.Data.OleDb; namespace PersonalManager { public partial class Form1 : Form { private string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Application.StartupPath + @"\dat.accdb;" + "Jet OLEDB:Database Password=xxx"; public Form1() { InitializeComponent(); button1.Click += (s, e) => { ExecuteNonQuery("create table employee(" + "id autoincrement primary key," + "name text" + ")"); ExecuteNonQuery("insert into employee (name) values ('taro')"); DataTable dt = ExecuteQuery("select * from employee"); List<Model> models = new List<Model>(); for (int r = 0; r < dt.Rows.Count; r++) { models.Add(new Model() { id = dt.Rows[r]["id"].ToString(), name = dt.Rows[r]["name"].ToString() }); } dataGridView1.DataSource = models; }; } private void ExecuteNonQuery(string commandText) { using (OleDbConnection con = new OleDbConnection(connectionString)) { con.Open(); using (OleDbCommand cmd = new OleDbCommand()) { try { cmd.Connection = con; cmd.CommandText = commandText; cmd.ExecuteNonQuery(); } catch (Exception e) { MessageBox.Show(e.Message); } } } } private void ExecuteNonQuery(List<string> commandTextList) { using (OleDbConnection con = new OleDbConnection(connectionString)) { con.Open(); using (OleDbCommand cmd = new OleDbCommand()) { cmd.Transaction = con.BeginTransaction(); try { foreach (string sql in commandTextList) { cmd.Connection = con; cmd.CommandText = sql; cmd.ExecuteNonQuery(); } cmd.Transaction.Commit(); } catch (Exception e) { MessageBox.Show(e.Message); cmd.Transaction.Rollback(); } } } } private DataTable ExecuteQuery(string commandText) { using (OleDbConnection con = new OleDbConnection(connectionString)) { try { con.Open(); using (OleDbCommand cmd = new OleDbCommand()) { cmd.Connection = con; cmd.CommandText = commandText; using (OleDbDataReader reader = cmd.ExecuteReader()) { DataTable dt = new DataTable(); dt.Load(reader); return dt; } } } catch (Exception e) { MessageBox.Show(e.Message); return new DataTable(); } } } } class Model { public string id { get; set; } public string name { get; set; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
textBox1.TextChanged += (s, e) => { string plainText = textBox1.Text; using (SHA256 sha256 = SHA256.Create()) { var encoded = Encoding.UTF8.GetBytes(plainText); var hash = sha256.ComputeHash(encoded); // ハッシュ値を16進数に変換(いくつか方法) textBox2.Text = String.Join("", hash.Select(x => x.ToString("x2")).ToArray()); textBox3.Text = BitConverter.ToString(hash).Replace("-", "").ToLower(); textBox4.Text = string.Concat(hash.Select(x => $"{x:x2}")); // ハッシュ値をBase64に変換の場合 textBox5.Text = Convert.ToBase64String(hash); } }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
private string Encrypt(string plainText) { // 半角16文字(128bit)、24文字(192bit)、32文字(256bit)から選ぶ。 byte[] key = Encoding.UTF8.GetBytes(@"u5vwged9ky6y6vii"); // Block Sizeと同じにする。半角16文字(128bit) byte[] iv = Encoding.UTF8.GetBytes(@"8knshgxqy4uf89gq"); byte[] byteValue = Encoding.UTF8.GetBytes(plainText); var byteLength = byteValue.Length; using (var aes = Aes.Create()) using (var encryptor = aes.CreateEncryptor(key, iv)) { var encryptValue = encryptor.TransformFinalBlock(byteValue, 0, byteLength); var base64Value = Convert.ToBase64String(encryptValue); return base64Value; } } public static string Decrypt(string encryptText) { byte[] key = Encoding.UTF8.GetBytes(@"u5vwged9ky6y6vii"); byte[] iv = Encoding.UTF8.GetBytes(@"8knshgxqy4uf89gq"); var byteValue = Convert.FromBase64String(encryptText); var byteLength = byteValue.Length; using (var aes = Aes.Create()) using (var decryptor = aes.CreateDecryptor(key, iv)) { var decryptValue = decryptor.TransformFinalBlock(byteValue, 0, byteLength); var stringValue = Encoding.UTF8.GetString(decryptValue); return stringValue; } } |