/// <summary> /// Callback for getting an <see cref="Image"/> asynchronously. /// We make this static and pass the <see cref="GrhTreeViewNode"/> as the <paramref name="userState"/> so we can /// just create a single delegate instance and pass that around, greatly reducing garbage and overhead of async operations. /// </summary> /// <param name="sender">The <see cref="GrhImageList"/> the callback came from.</param> /// <param name="gd">The <see cref="StationaryGrhData"/> that the <paramref name="image"/> is for. May be null if the /// <paramref name="image"/> is equal to <see cref="GrhImageList.ErrorImage"/> or null.</param> /// <param name="image">The <see cref="Image"/> that was created.</param> /// <param name="userState">The optional user state object that was passed to the method.</param> static void GrhImageListAsyncCallback(GrhImageList sender, StationaryGrhData gd, Image image, object userState) { var node = (GrhTreeViewNode)userState; // If the async callback was run on another thread, we will have to use Control.Invoke() to get it to the correct thread. // Unfortunately, this will result in a bit of overhead and create some garbage due to the parameter list, but // its the best we can do (as far as I can see) and GrhImageList avoids running a new thread when possible anyways so // it only really happens while loading. if (!node.TreeView.InvokeRequired) { SetNodeImage(node, image); } else { node.TreeView.Invoke(_setNodeImage, node, image); } }
/// <summary> /// Initializes the <see cref="GrhImageList"/> class. /// </summary> static GrhImageList() { // Load the folder images _openFolder = Resources.folderopen; _closedFolder = Resources.folder; // Create the error image var bmp = new Bitmap(16, 16, PixelFormat.Format32bppArgb); using (var g = System.Drawing.Graphics.FromImage(bmp)) { g.Clear(Color.White); g.DrawLine(Pens.Red, new Point(0, 0), new Point(bmp.Width, bmp.Height)); g.DrawLine(Pens.Red, new Point(bmp.Width, 0), new Point(0, bmp.Height)); } _errorImage = bmp; // Create the placeholder image _placeholder = ImageHelper.CreateSolid(1, 1, Color.White); // Load the instance _instance = new GrhImageList(); }
/// <summary> /// Initializes the <see cref="GrhTreeViewNode"/> class. /// </summary> static GrhTreeViewNode() { _grhImageList = GrhImageList.Instance; _asyncCallback = GrhImageListAsyncCallback; _setNodeImage = SetNodeImage; }
/// <summary> /// Callback for getting an <see cref="Image"/> asynchronously. /// We make this static and pass the <see cref="GrhTreeViewNode"/> as the <paramref name="userState"/> so we can /// just create a single delegate instance and pass that around, greatly reducing garbage and overhead of async operations. /// </summary> /// <param name="sender">The <see cref="GrhImageList"/> the callback came from.</param> /// <param name="gd">The <see cref="StationaryGrhData"/> that the <paramref name="image"/> is for. May be null if the /// <paramref name="image"/> is equal to <see cref="GrhImageList.ErrorImage"/> or null.</param> /// <param name="image">The <see cref="Image"/> that was created.</param> /// <param name="userState">The optional user state object that was passed to the method.</param> static void GrhImageListAsyncCallback(GrhImageList sender, StationaryGrhData gd, Image image, object userState) { var node = (GrhTreeViewNode)userState; var treeView = node.TreeView; if (treeView == null) return; // If the async callback was run on another thread, we will have to use Control.Invoke() to get it to the correct thread. // Unfortunately, this will result in a bit of overhead and create some garbage due to the parameter list, but // its the best we can do (as far as I can see) and GrhImageList avoids running a new thread when possible anyways so // it only really happens while loading. if (!treeView.InvokeRequired) SetNodeImage(node, image); else treeView.Invoke(_setNodeImage, node, image); }