Günther's profileGünther Foidl (gfoidl)PhotosBlogGuestbookMore ![]() | Help |
|
|
June 25 Drag a control at runtimeHow to drag a control at runtime is shown in the example. I’ve used a picturebox for demonstration. 1: using System.Drawing; 2: using System.Windows.Forms; 3: 4: namespace DragControlAtRuntime 5: {6: public partial class Form1 : Form 7: {8: private bool _dragging = false; 9: private Point _dragOffset; 10: //--------------------------------------------------------------------- 11: public Form1() 12: { 13: InitializeComponent(); 14: }15: //--------------------------------------------------------------------- 16: private void pictureBox1_MouseDown(object sender, MouseEventArgs e) 17: {18: if (!_dragging && (e.Button & MouseButtons.Left) == MouseButtons.Left) 19: {20: // Make the control capture the mouse so we receive MouseMove 21: // event if the user moves the mouse fast and it gets out of 22: // the control area: 23: pictureBox1.Capture = true; 24: 25: _dragging = true; 26: 27: // Remember where the control was clicked: 28: _dragOffset = new Point(-e.X, -e.Y); 29: } 30: }31: //--------------------------------------------------------------------- 32: private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 33: {34: if (_dragging) 35: {36: // The mouse location is relative to the control's top left 37: // corner but the location property must be relative to the 38: // parent's (i.e. form) top left corner: 39: Point location = new Point(e.X, e.Y); 40: 41: // The mouse location is relative to the top left corner 42: // of the control, make it relative to the top left corner 43: // of the screen: 44: location = pictureBox1.PointToScreen(location); 45: 46: // Make the location relative to the top left corner of the 47: // form: 48: location = this.PointToClient(location); 49: 50: // This is needed because the control is not necessarilly 51: // dragged from its top left corner: 52: location.Offset(_dragOffset); 53: 54: // Set the new location: 55: pictureBox1.Location = location; 56: } 57: }58: //--------------------------------------------------------------------- 59: private void pictureBox1_MouseUp(object sender, MouseEventArgs e) 60: {61: if (_dragging) 62: {63: _dragging = false; 64: pictureBox1.Capture = false; 65: } 66: } 67: } 68: }June 23 Thread nach Timeout beendenDas Beispiel zeigt wie eine Methode bzw. ein Thread welche die Methode ausführt nach einem bestimmten Timeout beendet falls die Methode noch nicht fertig ist. 1: #define LONG 2: //----------------------------------------------------------------------------- 3: using System; 4: using System.Threading; 5: 6: namespace ConsoleApplication1 7: {8: class Program 9: {10: static void Main(string[] args) 11: {12: // Wird zur Threadbenachrichtigung benötigt: 13: AutoResetEvent signal = new AutoResetEvent(false); 14: 15: // Wird benötigt da ThreadPool verwendet wird: 16: Thread workerThread = null; 17: 18: // Durch diese Variante gibt es den Vorteil dass 19: // die Worker-Methode nicht geändert werden muss. 20: ThreadPool.QueueUserWorkItem((o) => 21: {22: // Auf ThreadPool-Threads kann normalerweise nicht 23: // zugegriffen werden. Mit diesem "Trick" gehts. 24: workerThread = Thread.CurrentThread; 25: 26: // Worker starten: 27: Worker(); 28: 29: // Benachrichtigen dass Worker fertig ist: 30: signal.Set(); 31: }); 32: 33: // Timer starten der 5 Sekunden wartet und dann das Signal 34: // setzt. 35: new Timer((o) => { signal.Set(); }, null, 5000, Timeout.Infinite); 36: 37: // Warten bis das Signal gesetz ist: 38: signal.WaitOne(); 39: 40: // Prüfen ob der WorkerThread noch arbeitet. Falls ja den Thread 41: // abbrechen. Würde im Worker eine Schleife ausgeführt werden 42: // könnte diese eleganter beendet werden in dem Worker in eine 43: // Klasse gepackt wird und diese Klasse eine Methode 44: // RequestStop implementiert welche ein volatile-bool-Feld 45: // setzt welches in jedem Schleifendurchgang abgefragt wird. 46: // Ist dieses bool-Feld gesetz so beende die Arbeit. 47: if (workerThread != null && workerThread.IsAlive) 48: workerThread.Abort(); 49: 50: Console.WriteLine("Fertig."); 51: Console.ReadKey(); 52: }53: //--------------------------------------------------------------------- 54: /// <summary> 55: /// Arbeits-Methode. 56: /// </summary> 57: static void Worker() 58: {59: Console.WriteLine("In Worker"); 60: 61: // Lange Arbeit simulieren: 62: #if LONG 63: Thread.Sleep(200000);64: #else 65: Thread.Sleep(1000);66: #endif 67: Console.WriteLine("Worker fertig."); 68: } 69: } 70: }Happy coding ;) Comparison with Enumerable<T>.Distinct()See also Get unique elements from an IEnumerable<T> So when we use .net 3.5 why don’t we use list.Distinct().ToList() to get the same result? The proof that the above implementation is faster is given in the following chart: The code used for testing is given below. Note that the Garbage is collected prior to measuring so that the result aren’t influenced by the garbage collection during the measurement. 1: using System; 2: using System.Collections.Generic; 3: using System.Diagnostics; 4: using System.IO; 5: using System.Linq; 6: using gfoidl.Extensions; 7: 8: namespace Duplikate_entfernen 9: {10: class Program 11: {12: static void Main(string[] args) 13: {14: const int N = 1000000; 15: Stopwatch sw = new Stopwatch(); 16: File.Delete("result.csv"); 17: 18: for (int i = 0; i <= N; i += 10000) 19: {20: List<string> list = CreateTestList(i); 21: 22: GC.Collect(); 23: GC.WaitForPendingFinalizers(); 24: sw.Reset(); 25: sw.Start();26: list.GetDistinct(false); 27: sw.Stop();28: double ticks1 = sw.ElapsedTicks / (double)i; 29: 30: GC.Collect(); 31: GC.WaitForPendingFinalizers(); 32: sw.Reset(); 33: sw.Start(); 34: list.GetDistinctEnumerable().ToList(); 35: sw.Stop();36: double ticks2 = sw.ElapsedTicks / (double)i; 37: 38: GC.Collect(); 39: GC.WaitForPendingFinalizers(); 40: sw.Reset(); 41: sw.Start(); 42: list.Distinct().ToList(); 43: sw.Stop();44: double ticks3 = sw.ElapsedTicks / (double)i; 45: 46: string result = string.Format( 47: "{0};{1};{2};{3}\n", 48: i, ticks1, ticks2, ticks3);49: File.AppendAllText("result.csv", result); 50: Console.Write(result); 51: } 52: 53: #if !DEBUG 54: Process.Start("result.csv"); 55: #else 56: Console.ReadKey();57: #endif 58: }59: //--------------------------------------------------------------------- 60: private static List<string> CreateTestList(int n) 61: {62: string ident = Guid.NewGuid().ToString(); 63: List<string> list = new List<string>(n); 64: 65: for (int i = 0; i < n; i++) 66: if (i % 2 == 0) 67: list.Add(ident);68: else 69: list.Add(Guid.NewGuid().ToString()); 70: 71: return list; 72: } 73: } 74: }
Happy coding ;) Get unique elements from an IEnumerableSee also: Comparison with Enumerable<T>.Distinct() With the HashSet<T> implemented in .net 3.5 there is an efficient way for retrieving unique elements from an IEnumerable<T> (“remove duplicates”). Here’s the extension methods for that purpose (please apologize the German comments in the code ;). 1: namespace gfoidl.Extensions 2: {3: using System.Collections.Generic; 4: using System.Linq; 5: //------------------------------------------------------------------------- 6: /// <summary> 7: /// Erweiterungsmethoden für <see cref="IEnumerable<T>"/> 8: /// </summary> 9: public static class MyIEnumerableExtensions 10: {11: //--------------------------------------------------------------------- 12: /// <summary> 13: /// Gibt eine <see cref="List<T>"/> mit eindeutigen Werten 14: /// zurück. 15: /// </summary> 16: /// <typeparam name="T"> 17: /// Der Typ der aufzulistenden Objekte. 18: /// </typeparam> 19: /// <param name="collection"> 20: /// Die Auflistung. 21: /// </param> 22: /// <returns> 23: /// Auflistung ohne Duplikate. 24: /// </returns> 25: public static List<T> GetDistinct<T>( 26: this IEnumerable<T> collection) 27: {28: return collection.GetDistinct(false); 29: }30: //--------------------------------------------------------------------- 31: /// <summary> 32: /// Gibt eine <see cref="List<T>"/> mit eindeutigen Werten 33: /// zurück. 34: /// </summary> 35: /// <typeparam name="T"> 36: /// Der Typ der aufzulistenden Objekte. 37: /// </typeparam> 38: /// <param name="collection"> 39: /// Die Auflistung. 40: /// </param> 41: /// <param name="keepOrder"> 42: /// Gitb an ob die Reihenfolge der Elemente beibehalten werden soll. 43: /// </param> 44: /// <returns> 45: /// Auflistung ohne Duplikate. 46: /// </returns> 47: public static List<T> GetDistinct<T>( 48: this IEnumerable<T> collection, 49: bool keepOrder) 50: {51: if (keepOrder) 52: {53: HashSet<T> hashSet = new HashSet<T>(); 54: 55: // Eine Kapazität wird nicht angegeben da es sich gezeigt 56: // dass die Wahl dieser Größe sehr schwierig ist. Wird die 57: // Länge per Count ermittelt so wird über die ganze Enumeration 58: // iteriert und das ist die gleiche Aufwandsklasse wie das 59: // umkopieren der Elemente wenn keine Kapazität angegeben wird 60: // (beide sind O(n)). 61: List<T> result = new List<T>(); 62: 63: foreach (T item in collection) 64: if (hashSet.Add(item)) 65: result.Add(item); 66: 67: return result; 68: }69: else 70: return new HashSet<T>(collection).ToList(); 71: }72: //--------------------------------------------------------------------- 73: /// <summary> 74: /// Gibt ein <see cref="IEnumerable<T>"/> mit eindeutigen Werten 75: /// zurück. 76: /// </summary> 77: /// <typeparam name="T"> 78: /// Der Typ der aufzulistenden Objekte. 79: /// </typeparam> 80: /// <param name="collection"> 81: /// Die Auflistung. 82: /// </param> 83: /// <returns> 84: /// Auflistung ohne Duplikate. 85: /// </returns> 86: public static IEnumerable<T> GetDistinctEnumerable<T>( 87: this IEnumerable<T> collection) 88: {89: HashSet<T> hashSet = new HashSet<T>(); 90: foreach (T item in collection) 91: if (hashSet.Add(item)) 92: yield return item; 93: }94: //--------------------------------------------------------------------- 95: /// <summary> 96: /// Gibt eine <see cref="List<T>"/> mit eindeutigen Werten 97: /// zurück. 98: /// </summary> 99: /// <typeparam name="T"> 100: /// Der Typ der aufzulistenden Objekte. 101: /// </typeparam> 102: /// <param name="collection"> 103: /// Die Auflistung. 104: /// </param> 105: /// <param name="keepOrder"> 106: /// Gitb an ob die Reihenfolge der Elemente beibehalten werden soll. 107: /// </param> 108: /// <param name="comparer"> 109: /// Die <see cref="IEqualityComparer<T>"/>-Implementierung, die 110: /// zum Vergleichen von Schlüsseln verwendet werden soll, oder null, 111: /// wenn der Standard-<see cref="EqualityComparer<T>"/> für diesen 112: /// Schlüsseltyp verwendet werden soll. 113: /// </param> 114: /// <returns> 115: /// Auflistung ohne Duplikate. 116: /// </returns> 117: public static List<T> GetDistinct<T>( 118: this IEnumerable<T> collection, 119: bool keepOrder, 120: IEqualityComparer<T> comparer) 121: {122: if (keepOrder) 123: {124: HashSet<T> hashSet = new HashSet<T>(comparer); 125: List<T> result = new List<T>(); 126: 127: foreach (T item in collection) 128: if (hashSet.Add(item)) 129: result.Add(item); 130: 131: return result; 132: }133: else 134: return new HashSet<T>(collection, comparer).ToList(); 135: } 136: } 137: }June 08 Neuer Artikel auf Codeproject.comIch habe einen neuen Artikel auf Codeproject.com eingestellt. Thema: DataGridView that saves column order, width and visibility to user.config Weitere Artikel von mir auf Codeproject zeigt die Artikelübersicht. June 06 Hallo Welt!Für einen Programmierer wie mich sicher der Beste erste Blogeintrag. Bis demnächst, |
|
|