Here's the mock-up a client asked me to create:
Here's what I have in actual software:
The problem is that I need to be able to delete a picture from the control below. I don't know how to approach this problem. Any guidance whatsoever?
Here's the code to the custom user control I made:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WebServiceScanner
{
public partial class selectablePicture : UserControl
{
public selectablePicture(Image image)
{
InitializeComponent();
ptbImage.BackgroundImage = image;
ptbImage.BackgroundImageLayout = ImageLayout.Zoom;
}
public Image GetImage()
{
return ptbImage.BackgroundImage;
}
public bool IsSelected()
{
return chkSelected.Checked;
}
public void DisableCheckbox()
{
this.chkSelected.Enabled = false;
}
private void ptbImage_Click(object sender, EventArgs e)
{
SelectControl();
ptbImage.Focus();
ToggleCheckBox();
}
private void selectablePicture_Click(object sender, EventArgs e)
{
SelectControl();
this.Focus();
ToggleCheckBox();
}
private void ToggleCheckBox()
{
if (!chkSelected.Enabled == false)
{
if (chkSelected.Checked)
{
chkSelected.Checked = false;
}
else
{
chkSelected.Checked = true;
}
}
}
private void chkSelected_Click(object sender, EventArgs e)
{
SelectControl();
chkSelected.Focus();
}
private void SelectControl()
{
if (!chkSelected.Enabled == false)
{
this.BackColor = Color.FromArgb(89, 168, 248);
}
}
private void chkSelected_Leave(object sender, EventArgs e)
{
DeSelectControl();
}
private void ptbImage_Leave(object sender, EventArgs e)
{
DeSelectControl();
}
private void selectablePicture_Leave(object sender, EventArgs e)
{
DeSelectControl();
}
private void DeSelectControl()
{
//If none of the controls inside the usercontrol have focus, set this control to white.
if (!chkSelected.Enabled == false)
{
if (!this.Focused && !this.ptbImage.Focused && !this.chkSelected.Focused)
{
this.BackColor = Color.White;
}
}
}
}
}
And here's how I use it:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WebServiceScanner
{
public partial class MainForm : Form
{
int pictureXPosition = 0;
List<selectablePicture> Images;
public MainForm()
{
InitializeComponent();
ptbNewestPicture.BackgroundImageLayout = ImageLayout.Zoom;
Images = new List<selectablePicture>();
}
private void button1_Click(object sender, EventArgs e)
{
LoadImageFromScanner();
}
private void scanToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadImageFromScanner();
}
private void scanBatchToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadBatchImagesFromScanner();
}
private void btnScanBatch_Click(object sender, EventArgs e)
{
LoadBatchImagesFromScanner();
}
private void connectionSettingsToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowConfigurationForm();
}
private void LoadImageFromScanner()
{
selectablePicture picture = new selectablePicture(Image.FromFile(@"C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg"));
ptbNewestPicture.BackgroundImage = picture.GetImage();
picture.Location = new Point(pictureXPosition + panel1.AutoScrollPosition.X, 0);
panel1.Controls.Add(picture);
pictureXPosition += 130;
}
private void LoadBatchImagesFromScanner()
{
throw new NotImplementedException();
}
private void ShowConfigurationForm()
{
ConnectionSettingsForm connectionConfig = new ConnectionSettingsForm();
connectionConfig.ShowDialog();
}
private void btnDeleteSelected_Click(object sender, EventArgs e)
{
DeleteSelectedPictures();
}
private void DeleteSelectedPictures()
{
foreach (Control c in panel1.Controls)
{
if (((selectablePicture)c).IsSelected())
{
DisablePicture(c);
Images.Remove((selectablePicture)c);
}
}
}
private void DisablePicture(Control c)
{
c.BackColor = Color.Gray;
((selectablePicture)c).DisableCheckbox();
}
}
}
I thought about maintainin开发者_JAVA技巧g a list of my user control and redrawing the entire list every time something changes, but this is no good because what happens if there are a lot of pictures?
Any guidance?
What steps do I need to follow if I want to able to drag and reorder pictures? Thanks!
One solution would be not to render them as controls at all, but create a control that renders the thumbnails from left to right (modifying the rendering of the selected image based on whether it is selected or not).
Deleting an image is now trivial, it is just that, deleted. Then you no longer have to worry about it, it's no longer in your render list. No control removal required.
The overhead of this custom control will be less (1 control vs 'N' controls for each image).
There are many other advantages you can now do easily such as applying effects to nearby images, etc etc etc.. Granted this could be done with separate controls but this way it's MUCH less of a ball-ache.
Some Metrics
N = Total number of images
T_WIDTH = Thumbnail width
MARGIN_W = Margin you want either side of the thumbnail
CELL_W = T_WIDTH + (MARGIN_W * 2) (Total width of a cell that contains a thumbnail)
// Pseudo code here!!!
Scrollbar.Width = CELL_W * N
Scrollbar.PageWidth = Control.ClientWidth / CELL_W
Image index to start rendering at
Scrollbar.Pos / CELL_W
Remember to offset the actual x-location where you start rendering based on where that scrollbar position falls within CELL_W.
Use aFlowControlPanel
instead of a simple Panel
. Then you can add and remove controls from it and they will line themselves up.
精彩评论