问题
I have a form that will dynamically create user controls, and each of those user controls has a start button and a stop button. Is there a way to have a start all and stop all button on the form?
I tried having a Boolean that gets set true when the main form button is clicked, but once the user control is created it does not check the Boolean value.
Here is the code for the main form (vdoPlayer is the user control):
namespace AutoPopulateVideoSaving
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DisplayImage();
}
private void DisplayImage()
{
int h = 20;
for (int i = 0; i < 6; i++)
{
int w = i % 2;
vdoPlayer np = new vdoPlayer();
np.Location = new System.Drawing.Point((33 + 408 * w), h);
np.Name = "test" + i.ToString();
np.Size = new System.Drawing.Size(408, 266);
this.Controls.Add(np);
h = h + (266 * w);
}
}
private void StartAllBut_Click(object sender, EventArgs e)
{
}
private void StopAllBut_Click(object sender, EventArgs e)
{
}
}
}
Here is the code for the user control:
namespace AutoPopulateVideoSaving
{
public partial class vdoPlayer : UserControl
{
public vdoPlayer()
{
InitializeComponent();
VariableClass2.InitiateVariables();
JPEGStream jpegSource1 = new JPEGStream("http:// IP address /jpg/image.jpg?resolution=320x240");
jpegSource1.Login = username;
jpegSource1.Password = password;
jpegSource1.NewFrame += new NewFrameEventHandler(jpegSource1_NewFrame);
jpegSource1.VideoSourceError += new VideoSourceErrorEventHandler(jpegSource1_VideoSourceError);
Player1.VideoSource = jpegSource1;
}
void jpegSource1_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap image = new Bitmap(eventArgs.Frame, 320, 240);
image.Save(someFile, System.Drawing.Imaging.ImageFormat.Bmp);
}
void jpegSource1_VideoSourceError(object sender, VideoSourceErrorEventArgs eventArgs)
{
//Error handler
Debug.WriteLine(eventArgs.Description);
}
private void StartBut_Click(object sender, EventArgs e)
{
Player1.VideoSource.Start();
}
private void StopBut_Click(object sender, EventArgs e)
{
Player1.VideoSource.Stop();
}
}
}
I don't know what to put in Form1's button click events to control the rest. Like I said before, I tried using a Boolean, but it didn't work. Is this even possible?
回答1:
First, vdoPlayer
needs to expose this functionality for other objects to invoke. Something like this:
public void StartVideo()
{
Player1.VideoSource.Start();
}
public void StopVideo()
{
Player1.VideoSource.Stop();
}
(Once those are in place, that class' click handlers and other functionality should use those methods instead of invoking Start()
and Stop()
on VideoSource
directly, just for cleaner code.)
Additionally, the form should retain a list of all of its relevant controls. Something like this should do the trick:
public partial class Form1 : Form
{
private List<vdoPlayer> videoPlayers;
public Form1()
{
InitializeComponent();
videoPlayers = new List<vdoPlayer>();
DisplayImage();
}
// etc.
}
Any time such a control is dynamically created, simply add it to that list. When it's destroyed, remove it from the list. (You could skip the explicit list and try to dynamically traverse Controls
collections to build the list on the fly, but that can get pretty ugly.)
Now your form's buttons just need to invoke the operations on the video player controls:
private void StartAllBut_Click(object sender, EventArgs e)
{
foreach (var videoPlayer in videoPlayers)
videoPlayer.StartVideo();
}
private void StopAllBut_Click(object sender, EventArgs e)
{
foreach (var videoPlayer in videoPlayers)
videoPlayer.StopVideo();
}
来源:https://stackoverflow.com/questions/27530344/how-do-i-control-multiple-user-controls-with-one-button-in-windows-form