Windows Formada dizaynda ishlash murakkab. Drag&Drop - dasturga o`zgacha ko`rinish beradi va bu ajoyib imkoniyat ham. Uning tayyor kodini olib ishlatish esa undanda ko`proq zavq-shavq beradi :-) Oldingi versiyada aytilganidek biror paneldan boshqasiga ko`chirib o`tkazilganini tutib qolinadi va unga Action bajartiriladi. DragDropContainerdan TaskList yasashda foydalanish mumkin bo`ldi. Shuningdek har bir panel tepasiga sarlavha ko`rinishida soha nomini yozib qo`yish mumkin, hamda sohalarga border rangini ham tanlash mumkin bo`ldi.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace Library.Controls
{
public class DragDropContainer : Control
{
private readonly Panel _content = new Panel
{
Dock = DockStyle.Fill,
Padding = new Padding(0)
};
private readonly Panel _header = new Panel
{
Padding = new Padding(0),
Height = 20,
Dock = DockStyle.Top
};
private Action _action;
private bool _mouseDown;
private string _oldPosition;
private Point _point = new Point(0, 0);
public DragDropContainer()
{
Controls.Add(_header);
Controls.Add(_content);
_content.BringToFront();
}
public int ColumnCount { get; set; }
public Color BorderColor { get; set; } = Color.FromArgb(202, 210, 214);
public IEnumerable> Child => _content.Controls.OfType().Select(x => x.Child);
public IEnumerable
public IEnumerable Panels => _content.Controls.OfType();
for (var i = 0; i < ColumnCount; i++)
{
var panel = new DragDropPanel
{
Name = "" + i,
Width = Width/ColumnCount,
Dock = DockStyle.Right,
Padding = new Padding(5)
};
var label = new Label
{
AutoSize = false,
Width = panel.Width,
Padding = new Padding(0),
Dock = DockStyle.Right,
Name = "" + i,
TextAlign = ContentAlignment.MiddleCenter
};
_content.Controls.Add(panel);
_header.Controls.Add(label);
dragDropContainer1.ColumnCount = 5;
var linkLabel = new LinkLabel
{
Name ="test1",
Text = "Ism Familiya"
};
dragDropContainer1.Add(linkLabel, 1);
dragDropContainer1.Headers.FirstOrDefault().Text = "1-soha";
dragDropContainer1.Headers.ToArray()[2].Text = "2- soha";
dragDropContainer1.SetHandler((i, control) =>
{
MessageBox.Show(string.Format("{0},{1}", i, (control as LinkLabel)?.Text));
var position = dragDropContainer1.Child;
});
Bu versiyada panellar tartiblandi. Tartib chapdan o`ngga davom etadi. DragDropContainer ga kiritilgan controllar qaysi o`rinda turgani ham ko`rish mumkin.
Keyingi versiyada har bir harakatni, biror paneldan boshqasiga ko`chirib o`tkazilganini tutib qolamiz va unga Action bajartiramiz. So`ng bu DragDropContainerdan TaskList yasashda foydalanish mumkin bo`ladi.
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace ControlsLibrary.Controls
{
public class DragDropContainer : Control
{
private bool _mouseDown;
private Point _point = new Point(0, 0);
public int ColumnCount { get; set; }
public IEnumerable> Child => Controls.OfType().Select(x => x.Child);
public static T Get(string body){ body.XmlToObject(); }
dasturning kodi
internal static class XmlJsonExt { public static T Deserialize(this string data) { return JsonConvert.DeserializeObject(data); } public static T XmlToObject(this string data) { return CreateDocument(data).XmlToJson().Deserialize(); } #region Utils private static XmlDocument CreateDocument(string body) { var document = new XmlDocument(); document.InnerXml = body; return document; } private static string XmlToJson(this XmlDocument xmlDoc) { var sbJson = new StringBuilder(); sbJson.Append("{ "); XmlToJsoNnode(sbJson, xmlDoc.DocumentElement, true); sbJson.Append("}"); return sbJson.ToString(); } // XmlToJSONnode: Output an XmlElement, possibly as part of a higher array private static void XmlToJsoNnode(StringBuilder sbJson, XmlElement node, bool showNodeName) { if (showNodeName) sbJson.Append("\"" + SafeJson(node.Name) + "\": "); sbJson.Append("{"); // Build a sorted list of key-value pairs // where key is case-sensitive nodeName // value is an ArrayList of string or XmlElement // so that we know whether the nodeName is an array or not. var childNodeNames = new SortedList(); // Add in all node attributes if (node.Attributes != null) foreach (XmlAttribute attr in node.Attributes) StoreChildNode(childNodeNames, attr.Name, attr.InnerText); // Add in all nodes foreach (XmlNode cnode in node.ChildNodes) { if (cnode is XmlText) StoreChildNode(childNodeNames, "value", cnode.InnerText); else if (cnode is XmlElement) StoreChildNode(childNodeNames, cnode.Name, cnode); } // Now output all stored info foreach (string childname in childNodeNames.Keys) { var alChild = (ArrayList) childNodeNames[childname]; if (alChild.Count == 1) OutputNode(childname, alChild[0], sbJson, true); else { sbJson.Append(" \"" + SafeJson(childname) + "\": [ "); foreach (var child in alChild) OutputNode(childname, child, sbJson, false); sbJson.Remove(sbJson.Length - 2, 2); sbJson.Append(" ], "); } } sbJson.Remove(sbJson.Length - 2, 2); sbJson.Append(" }"); } // StoreChildNode: Store data associated with each nodeName // so that we know whether the nodeName is an array or not. private static void StoreChildNode(SortedList childNodeNames, string nodeName, object nodeValue) { // Pre-process contraction of XmlElement-s if (nodeValue is XmlElement) { // Convert into "aa":null // xx into "aa":"xx" var cnode = (XmlNode) nodeValue; if (cnode.Attributes.Count == 0) { var children = cnode.ChildNodes; if (children.Count == 0) nodeValue = null; else if (children.Count == 1 && (children[0] is XmlText)) nodeValue = ((XmlText) (children[0])).InnerText; } } // Add nodeValue to ArrayList associated with each nodeName // If nodeName doesn't exist then add it var oValuesAl = childNodeNames[nodeName]; ArrayList valuesAl; if (oValuesAl == null) { valuesAl = new ArrayList(); childNodeNames[nodeName] = valuesAl; } else valuesAl = (ArrayList) oValuesAl; valuesAl.Add(nodeValue); } private static void OutputNode(string childname, object alChild, StringBuilder sbJson, bool showNodeName) { if (alChild == null) { if (showNodeName) sbJson.Append("\"" + SafeJson(childname) + "\": "); sbJson.Append("null"); } else if (alChild is string) { if (showNodeName) sbJson.Append("\"" + SafeJson(childname) + "\": "); var sChild = (string) alChild; sChild = sChild.Trim(); sbJson.Append("\"" + SafeJson(sChild) + "\""); } else XmlToJsoNnode(sbJson, (XmlElement) alChild, showNodeName); sbJson.Append(", "); } // Make a string safe for JSON private static string SafeJson(string sIn) { var sbOut = new StringBuilder(sIn.Length); foreach (var ch in sIn) { if (Char.IsControl(ch) || ch == '\'') { int ich = ch; sbOut.Append(@"\u" + ich.ToString("x4")); continue; } if (ch == '\"' || ch == '\\' || ch == '/') { sbOut.Append('\\'); } sbOut.Append(ch); } return sbOut.ToString(); } #endregion }
Odatsa asynchrone usulda controllarni formada joylashtirganda xatolik yuz beradi, ammo bunday qilmasa dastur sekin ishlashi tabiiy(agar katta dastur bo`lsa)
Buning yo`li oson:
Extention yozib olamiz ,
public static class ControlExt {
public static void Asynch(this TControl control, Action action) where TControl : Control { if (control.InvokeRequired) control.Invoke(action, control); else action(control); } }
Extentionimiz tayyor, endi istagan yerda asynchrone usulda qo`shaveramiz,
content.Asynch(delegate (Panel panel) { panel.Add(new Malumotnoma { Name = "malumotnoma", Dock = DockStyle.Fill, EmployeeCode = Code }, "Malumotnoma"); });
Sqlite da atigi bir nechta funksiya bor, oddiy dasturlar uchun bu yetarli. Lekin murakkabroq so`rovlarni tuzish uchun bu albatta kamlik qiladi. Shu sababli Sqlite o`ziga qo`shimcha funksiya yozib undan keng foydalanishimiz uchun darvozalarini ochib qo`ygan.
Biz istan tipdagi funksiyani qo`shib, unga maxsus logikani ishlatishimiz mumkin. Bu funksiyalar yacheykalar bo`yicha har bir ustun uchun alohida tepadan pastga qarab ishlaydi. Aggregate funksiyalar 1 dona natija qaytaradi(masalan: sum, min, max,avg, count,..), Scalar funksiyalar satrlarning soniga teng natija qaytaradi.(length, lower, upper, day, year,...)
Foydalanish tartibi: 1. Yangi funksiyamizni Connection dan ro`yxatdan o`tkazamiz
_connection.BindFunction(new Lower());
2. Yangi funksiya tanasi
using System; using System.Data.SQLite; namespace SQLite.CustomFunction { [SQLiteFunction(Name = "lower", Arguments = 1, FuncType = FunctionType.Scalar)] public sealed class Lower : SQLiteFunction { public override object Invoke(object[] args) { return args.Length > 0 ? (args[0].ToString() ?? "").ToLower() : null; } } }
Sqliteda lower funksiyasi bor, ammo u krill harfi uchun ishlamaydi, bizni yangi funksiyamiz Sqlite ning funksiyasini qayta yuklaydi(override, overload). Esda tuting: Bu so`rov sqlite browserida ishlamaydi, chunki uning kodida bu funksiya yo`q, faqat bizning ulanish usluniimizdagi ro`yxatga olingan dasturimizda ishlaydi