Timer event is not triggering button click - c#

I'm trying transfer Image file for each 3 seconds from source to destination directory, when I click on the "Start" button. And "Stop" button is for stopping the file transfer.
If I use the Start button for the third time, the event is not firing; so, the files are not transferring.
The progress I've done is in the below:
Start --- File Transferring; Pressed STOP Button // It Works as well.
Start --- File Transferring; Pressed STOP Button // It works as well.
Start ----- File is not transferring, Event is not firing // It not works!
What I've done for solving the problem:
I put a break-point in the Tick event and the tick event is not firing.
I Checked that SourceFiles.Count is greater than the TransferCount (SourceFiles.Count > TransferCount).
I noticed that during the file transfer, if I click Stop button during a file transfer that particular file remains un-transferred.
How can i fix this? Thank you in advance.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Threading;
namespace GridTest
{
/// <summary>
/// Interaction logic for Window3.xaml
/// </summary>
public partial class Window3 : Window
{
DispatcherTimer dispatcherTimer = new DispatcherTimer();
private static List<string> SourceFiles = new List<string>();
private static readonly string SourceDir = #"C:\TestFiles\Images\";
private static readonly string DestinationDir = #"C:\Files\Images\3_5x5\";
private static int TransferCount = 0;
public Window3()
{
InitializeComponent();
this.Loaded += Window3_Loaded;
}
void Window3_Loaded(object sender, RoutedEventArgs e)
{
dispatcherTimer.Interval = new TimeSpan(0, 0, 3);
dispatcherTimer.Tick += dt_Tick;
}
void dt_Tick(object sender, EventArgs e)
{
if (TransferCount < SourceFiles.Count)
{
var fileName = System.IO.Path.GetFileName(SourceFiles[TransferCount]);
var destFile = System.IO.Path.Combine(DestinationDir, fileName);
System.IO.File.Copy(SourceFiles[TransferCount], destFile,true);
System.IO.File.Delete(SourceFiles[TransferCount]);
Console.WriteLine(string.Format("Total Files: {0} Number of files transferred: {1}", SourceFiles.Count, TransferCount + 1));
TransferCount += 1;
}
else
{
Console.WriteLine(string.Format("Total number of files transferred: {0}. Transfer Completed", TransferCount + 1));
(sender as DispatcherTimer).Stop();
(sender as DispatcherTimer).Tick -= dt_Tick;
}
}
private void Start_Click(object sender, RoutedEventArgs e)
{
if (!System.IO.Directory.Exists(DestinationDir))
{
System.IO.Directory.CreateDirectory(DestinationDir);
}
if (System.IO.Directory.Exists(SourceDir))
{
SourceFiles = Directory.GetFiles(SourceDir).ToList();
}
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
dispatcherTimer.Stop();
}
}
}

If you call Stop, your timer event should not fire until you set IsEnabled property to true.
So I suggest to do a bit of refactoring
void Window3_Loaded(object sender, RoutedEventArgs e)
{
LoadSourceFiles();
StartTimer();
}
void StartTimer()
{
dispatcherTimer.Interval = new TimeSpan(0, 0, 3);
dispatcherTimer.Tick += dt_Tick;
dispatcherTimer.IsEnabled = true;
}
void LoadSourceFiles()
{
if (!System.IO.Directory.Exists(DestinationDir))
{
System.IO.Directory.CreateDirectory(DestinationDir);
}
if (System.IO.Directory.Exists(SourceDir))
{
SourceFiles = Directory.GetFiles(SourceDir).ToList();
}
}
and call this method every time you press the Start button
private void Start_Click(object sender, RoutedEventArgs e)
{
StartTimer();
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
dispatcherTimer.IsEnabled = false;
}
I suggest also to reset the global variable that keeps track of the files transfered to zero when inside the Tick event you discover that every file has been transfered (or disable the Start button)
....
else
{
Console.WriteLine(string.Format("Total number of files transferred: {0}. Transfer Completed", TransferCount + 1));
(sender as DispatcherTimer).Stop();
(sender as DispatcherTimer).Tick -= dt_Tick;
TransferCount = 0;
}
Otherwise if you restart the timer in this situation it will stop immediately

Not really an answer, but here's a re-factored version which doesn't use timer. Instead, it uses TaskEx.Delay and async/await, untested (targeting .NET 4.0 with vs2012+ and Microsoft.Bcl.Async):
using System;
using System.Collections.Generic;
using System.Windows;
using System.Threading;
using System.Threading.Tasks;
namespace GridTest
{
/// <summary>
/// Interaction logic for Window3.xaml
/// </summary>
public partial class Window3 : Window
{
private static List<string> SourceFiles = new List<string>();
private static readonly string SourceDir = #"C:\TestFiles\Images\";
private static readonly string DestinationDir = #"C:\Files\Images\3_5x5\";
public Window3()
{
InitializeComponent();
this.Loaded += Window3_Loaded;
}
void Window3_Loaded(object sender, RoutedEventArgs e)
{
}
async Task DoWorkAsync(CancellationToken token)
{
int transferCount;
for (transferCount = 0; transferCount < SourceFiles.Count; transferCount++)
{
token.ThrowIfCancellationRequested();
var fileName = System.IO.Path.GetFileName(SourceFiles[transferCount]);
var destFile = System.IO.Path.Combine(DestinationDir, fileName);
System.IO.File.Copy(SourceFiles[transferCount], destFile, true);
System.IO.File.Delete(SourceFiles[transferCount]);
Console.WriteLine(string.Format("Total Files: {0} Number of files transferred: {1}", SourceFiles.Count, transferCount + 1));
transferCount += 1;
await TaskEx.Delay(3000, token); // 3s delay
}
Console.WriteLine(string.Format("Total number of files transferred: {0}. Transfer Completed", transferCount + 1));
}
CancellationTokenSource _cts;
Task _task;
private void Start_Click(object sender, RoutedEventArgs e)
{
if (_cts != null)
_cts.Cancel();
_cts = new CancellationTokenSource();
_task = TaskEx.Run(() => DoWorkAsync(_cts.Token), _cts.Token);
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
if (_cts != null)
_cts.Cancel();
}
}
}

You never call Start on the DispatchTimer.
Add this to the Window3_Loaded method:
dispatcherTimer.Start();

Related

Updating progressbar from another class in c#

I'm having an issue getting a progressbar to show download progress. The files are downloading without issue, but something is causing my progressbar to not update and I can't figure out why.
I've tried setting the progressBar value manually in the download and wc_DownloadProgressChanged method, but the only place it actually changes is the Form1_Load method.
using System;
using System.Windows.Forms;
using System.Threading;
namespace Launch
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Downloader downloader = new Downloader();
ThreadStart job = new ThreadStart(downloader.download);
Thread thread = new Thread(job);
thread.Start();
}
private void ProgressBar_Click(object sender, EventArgs e)
{
}
public void SetProgress(int val)
{
progressBar.Value = val;
}
public void SetVisible(bool val)
{
progressBar.Visible = val;
}
}
}
using System;
using System.Data;
using System.Net;
using Newtonsoft.Json;
namespace Launch
{
class Downloader
{
public void download()
{
WebClient client = new WebClient();
string url = "https://someurl.com/manifest.json";
string json = client.DownloadString(url);
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);
DataTable dataTable = dataSet.Tables["Required"];
foreach (DataRow row in dataTable.Rows)
{
string remoteUri = row["url"].ToString();
string fileName = row["name"].ToString();
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadFile(remoteUri, fileName);
Console.WriteLine("Did something with " + remoteUri);
}
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
var form = new Form1();
form.SetProgress(e.ProgressPercentage);
}
}
}
Would anyone be able to shed some light on what I'm doing wrong here?
EDIT:
I was able to get this working for the most part using DownloadFileAsync, but the progress bar was bouncing back and forth, I'm assuming because it's trying to calculate the progress for each individual file as bytes are received, so I'd like to get this working with DownloadFile.
The issue I'm now having with DownloadFile is that I have it running as a task but it's skipping all of the files (not downloading any of them, just prints them all out to console super fast).
Here's the code I'm using currently:
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
string url = "https://someurl.com/manifest.json";
string json = client.DownloadString(url);
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);
DataTable dataTable = dataSet.Tables["Required"];
foreach (DataRow row in dataTable.Rows)
{
string remoteUri = row["url"].ToString();
string fileName = row["name"].ToString();
Task.Run(() => {
client.DownloadFile(remoteUri, fileName);
});
Console.WriteLine("Did something with " + remoteUri);
}
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate {
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
label1.Text = "Downloaded ";
label2.Text = e.BytesReceived.ToString();
label3.Text = e.TotalBytesToReceive.ToString();
progressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
});
}
Any ideas?
Use this code below :
private void Form1_Load(object sender, EventArgs e)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadStringCompleted += client_DownloadStringCompleted;
Uri url = new Uri("url");
client.DownloadStringAsync(url);
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
SetVisible(false);
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
SetProgress(e.ProgressPercentage);
}
public void SetProgress(int val)
{
progressBar.Value = val;
}
public void SetVisible(bool val)
{
progressBar.Visible = val;
}
This likely should belong to https://codereview.stackexchange.com/
First of all, do not add a handler in a loop
client.DownloadProgressChanged += client_DownloadProgressChanged;
First time it will be fine, on 2nd item it will be called 2x times, on 3rd time it will be called 3 times, etc. You want to set handler once. Move it just after line:
WebClient client = new WebClient();
Second of all, each time a progress update is fired you are creating a new instance of the form. Create a private variable or property once.
private Form1 form = new Form1();
edit:
In case of UI, usually you can modify it only in the dispatcher thread that created it or use marshaling. I would just remove it as our already downloading the string async.
Also, I would not use e.ProgressPercentage, but something like:
Math.Truncate(e.BytesReceived / (double)e.TotalBytesToReceive * 100)

How can I show correctly a progressbar and a label (that show the percentage) for filling multiple datasets?

I need to update a DataGridView that has master detail part, I'm trying to use this control for the grid (I use 4 datasets for filling the grid).
Question: how can I add correctly a thread or more that will add to the grid these datasets and show the correct percentage and the same time the UI remain usable(responsive, not to become "not responding" for user)?
In every table I have about 10000 rows.
Please provide some code if possible, because I'm stuck.
Thanks in advance,
Steve
I tried like this, but I'm stuck at showing the user the correct percentage and correctly using the thread:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MasterDetail
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
MasterControl masterDetail;
private void frmMain_Load(object sender, EventArgs e)
{
//label1.Text = DateTime.Now.ToString();
clearFields();
loadData();
//label2.Text = DateTime.Now.ToString();
}
void clearFields()
{
panelView.Controls.Clear();
masterDetail = null;
Refresh();
masterDetail = new MasterControl(nwindDataSet);
panelView.Controls.Add(masterDetail);
}
internal delegate void SetDataSourceDelegate();
private void setDataSource()
{
if (this.masterDetail.InvokeRequired)
{
this.masterDetail.BeginInvoke(new SetDataSourceDelegate(setDataSource));
}
else
{
createMasterDetailView();
}
}
void loadData()
{
System.Threading.Thread thread =
new System.Threading.Thread(new System.Threading.ThreadStart(delegate() { loadDataThread(); }));
thread.Start();
}
void loadDataThread()
{
orderReportsTableAdapter.Fill(nwindDataSet.OrderReports);
invoicesTableAdapter.Fill(nwindDataSet.Invoices);
employeesTableAdapter.Fill(nwindDataSet.Employees);
customersTableAdapter.Fill(nwindDataSet.Customers);
setDataSource();
}
void createMasterDetailView()
{
masterDetail.setParentSource(nwindDataSet.Customers.TableName, "CustomerID");
masterDetail.childView.Add(nwindDataSet.OrderReports.TableName, "Orders");
masterDetail.childView.Add(nwindDataSet.Invoices.TableName, "Invoices");
masterDetail.childView.Add(nwindDataSet.Employees.TableName, "Employees");
typeof(DataGridView).InvokeMember("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.SetProperty, null,
masterDetail, new object[] { true });
foreach (DataGridView dvg in masterDetail.childView.childGrid)
{
typeof(DataGridView).InvokeMember("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.SetProperty, null,
dvg, new object[] { true });
}
masterDetail.childView.childGrid[2].RowTemplate.Height = 100;
}
private void btnLoad_Click_1(object sender, EventArgs e)
{
Application.Exit();
}
}
}
I think it would be better for you to use a backgroundworker
It has an event called WorkerReportsProgress that can help you create the progressbar you need.
Here is the sample code from msdn:
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
}
private void startAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
}
}
private void cancelAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
// Cancel the asynchronous operation.
backgroundWorker1.CancelAsync();
}
}
// This event handler is where the time-consuming work is done.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 10; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(500);
worker.ReportProgress(i * 10);
}
}
}
// This event handler updates the progress.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
resultLabel.Text = (e.ProgressPercentage.ToString() + "%");
}
// This event handler deals with the results of the background operation.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
resultLabel.Text = "Canceled!";
}
else if (e.Error != null)
{
resultLabel.Text = "Error: " + e.Error.Message;
}
else
{
resultLabel.Text = "Done!";
}
}
you just need to add the proper computation of the percentage and you're done

How can i add links to wpf xmal design by run time code?

I can't figure out how the whole thing is built. Do i need to add each link by my self manually ? And if i have 100 links ?
This is a screenshot of what i see in the xmal file
But maybe i can add this links from the code it self ?
The code is long so i will not add it to here.
I got the project from here:
Background File Downloader
If i want to add to the downloader my own links ?
I see in the DownloaderDemo code this part that add the links:
// Get the contents of the rich text box
string rtbContents = new TextRange(rtbPaths.Document.ContentStart, rtbPaths.Document.ContentEnd).Text;
foreach (string line in rtbContents.Split('\n'))
{
String trimmedLine = line.Trim(' ', '\r');
if (trimmedLine.Length > 0)
{
// If the line is not empty, assume it's a valid url and add it to the files list
// Note: You could check if the url is valid before adding it, and probably should do this is a real application
downloader.Files.Add(new FileDownloader.FileInfo(trimmedLine));
}
}
But i don't understand what richTextBox ? I guess it's in the design in the DownloaderDemo.xaml
Still if i want to add my own links to download files ?
This is DownloaderDemo.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace FileDownloaderApp
{
/// <summary>Interaction logic for DownloaderDemo.xaml</summary>
public partial class DownloaderDemo : Window
{
// Creating a new instance of a FileDownloader
private FileDownloader downloader = new FileDownloader();
public DownloaderDemo()
{
InitializeComponent();
CommandBindings.Add(new CommandBinding(ApplicationCommands.Close,
new ExecutedRoutedEventHandler(delegate(object sender, ExecutedRoutedEventArgs args) { this.Close(); })));
downloader.StateChanged += new EventHandler(downloader_StateChanged);
downloader.CalculatingFileSize += new FileDownloader.CalculatingFileSizeEventHandler(downloader_CalculationFileSize);
downloader.ProgressChanged += new EventHandler(downloader_ProgressChanged);
downloader.FileDownloadAttempting += new EventHandler(downloader_FileDownloadAttempting);
downloader.FileDownloadStarted += new EventHandler(downloader_FileDownloadStarted);
downloader.Completed += new EventHandler(downloader_Completed);
downloader.CancelRequested += new EventHandler(downloader_CancelRequested);
downloader.DeletingFilesAfterCancel += new EventHandler(downloader_DeletingFilesAfterCancel);
downloader.Canceled += new EventHandler(downloader_Canceled);
}
public void DragWindow(object sender, MouseButtonEventArgs args)
{
DragMove();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.Height -= 30;
}
// A simple implementation of setting the directory path, adding files from a textbox and starting the download
private void btnStart_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog openFolderDialog = new System.Windows.Forms.FolderBrowserDialog();
if (openFolderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// Set the path to the local directory where the files will be downloaded to
downloader.LocalDirectory = openFolderDialog.SelectedPath;
// Clear the current list of files (in case it's not the first download)
downloader.Files.Clear();
// Get the contents of the rich text box
string rtbContents = new TextRange(rtbPaths.Document.ContentStart, rtbPaths.Document.ContentEnd).Text;
foreach (string line in rtbContents.Split('\n'))
{
String trimmedLine = line.Trim(' ', '\r');
if (trimmedLine.Length > 0)
{
// If the line is not empty, assume it's a valid url and add it to the files list
// Note: You could check if the url is valid before adding it, and probably should do this is a real application
downloader.Files.Add(new FileDownloader.FileInfo(trimmedLine));
}
}
// Start the downloader
downloader.Start();
}
}
private void btnPause_Click(object sender, RoutedEventArgs e)
{
// Pause the downloader
downloader.Pause();
}
private void btnResume_Click(object sender, RoutedEventArgs e)
{
// Resume the downloader
downloader.Resume();
}
private void btnStop_Click(object sender, RoutedEventArgs e)
{
// Stop the downloader
// Note: This will not be instantantanious - the current requests need to be closed down, and the downloaded files need to be deleted
downloader.Stop();
}
// This event is fired every time the paused or busy state is changed, and used here to set the controls of the interface
// This makes it enuivalent to a void handling both downloader.IsBusyChanged and downloader.IsPausedChanged
private void downloader_StateChanged(object sender, EventArgs e)
{
// Setting the buttons
btnStart.IsEnabled = downloader.CanStart;
btnStop.IsEnabled = downloader.CanStop;
btnPause.IsEnabled = downloader.CanPause;
btnResume.IsEnabled = downloader.CanResume;
// Enabling or disabling the setting controls
rtbPaths.IsReadOnly = downloader.IsBusy;
cbUseProgress.IsEnabled = !downloader.IsBusy;
}
// Show the progress of file size calculation
// Note that these events will only occur when the total file size is calculated in advance, in other words when the SupportsProgress is set to true
private void downloader_CalculationFileSize(object sender, Int32 fileNr)
{
lblStatus.Content = String.Format("Calculating file sizes - file {0} of {1}", fileNr, downloader.Files.Count);
}
// Occurs every time of block of data has been downloaded, and can be used to display the progress with
// Note that you can also create a timer, and display the progress every certain interval
// Also note that the progress properties return a size in bytes, which is not really user friendly to display
// The FileDownloader class provides static functions to format these byte amounts to a more readible format, either in binary or decimal notation
private void downloader_ProgressChanged(object sender, EventArgs e)
{
pBarFileProgress.Value = downloader.CurrentFilePercentage();
lblFileProgress.Content = String.Format("Downloaded {0} of {1} ({2}%)", FileDownloader.FormatSizeBinary(downloader.CurrentFileProgress), FileDownloader.FormatSizeBinary(downloader.CurrentFileSize), downloader.CurrentFilePercentage()) + String.Format(" - {0}/s", FileDownloader.FormatSizeBinary(downloader.DownloadSpeed));
if (downloader.SupportsProgress)
{
pBarTotalProgress.Value = downloader.TotalPercentage();
lblTotalProgress.Content = String.Format("Downloaded {0} of {1} ({2}%)", FileDownloader.FormatSizeBinary(downloader.TotalProgress), FileDownloader.FormatSizeBinary(downloader.TotalSize), downloader.TotalPercentage());
}
}
// This will be shown when the request for the file is made, before the download starts (or fails)
private void downloader_FileDownloadAttempting(object sender, EventArgs e)
{
lblStatus.Content = String.Format("Preparing {0}", downloader.CurrentFile.Path);
}
// Display of the file info after the download started
private void downloader_FileDownloadStarted(object sender, EventArgs e)
{
lblStatus.Content = String.Format("Downloading {0}", downloader.CurrentFile.Path);
lblFileSize.Content = String.Format("File size: {0}", FileDownloader.FormatSizeBinary(downloader.CurrentFileSize));
lblSavingTo.Content = String.Format("Saving to {0}\\{1}", downloader.LocalDirectory, downloader.CurrentFile.Name);
}
// Display of a completion message, showing the amount of files that has been downloaded.
// Note, this does not hold into account any possible failed file downloads
private void downloader_Completed(object sender, EventArgs e)
{
lblStatus.Content = String.Format("Download complete, downloaded {0} files.", downloader.Files.Count);
}
// Show a message that the downloads are being canceled - all files downloaded will be deleted and the current ones will be aborted
private void downloader_CancelRequested(object sender, EventArgs e)
{
lblStatus.Content = "Canceling downloads...";
}
// Show a message that the downloads are being canceled - all files downloaded will be deleted and the current ones will be aborted
private void downloader_DeletingFilesAfterCancel(object sender, EventArgs e)
{
lblStatus.Content = "Canceling downloads - deleting files...";
}
// Show a message saying the downloads have been canceled
private void downloader_Canceled(object sender, EventArgs e)
{
lblStatus.Content = "Download(s) canceled";
pBarFileProgress.Value = 0;
pBarTotalProgress.Value = 0;
lblFileProgress.Content = "-";
lblTotalProgress.Content = "-";
lblFileSize.Content = "-";
lblSavingTo.Content = "-";
}
// Setting the SupportsProgress property - if set to false, no total progress data will be avaible!
private void cbUseProgress_Checked(object sender, RoutedEventArgs e)
{
downloader.SupportsProgress = (Boolean)cbUseProgress.IsChecked;
}
// Setting the DeleteCompletedFilesAfterCancel property - indicates if the completed files should be deleted after cancellation
private void cbDeleteCompletedFiles_Checked(object sender, RoutedEventArgs e)
{
downloader.DeleteCompletedFilesAfterCancel = (Boolean)cbDeleteCompletedFiles.IsChecked;
}
// Close the window when the close button is hit
private void btnClose_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}
You can easily add to the rich text box new download links by creating your own function that takes a new download link path, to append to the text box you do:
richTextBox.AppendText("new string of download link");
You're not sure what rich text box? It is in your .xaml file, it is called rtbPaths. So you could create a new button that executes a dialog box, takes a string and use that string to append to this text box.
It's hard to understand what is being asked here as well, sorry if I got this wrong.

Using AFORGE to record the videos in c#

i've try the following way to record the video from the Webcam by 25 Frame-rate per sec for 10sec but when i get the out put video it is of 2sec and the frames are played to fast as compare to the video stream.
The code is as follows.
using System;
using System.Drawing;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Threading;
using AForge.Video.FFMPEG;
namespace AforgeTutorial
{
public partial class Form1 : Form
{
private FilterInfoCollection ListOfCams;
private VideoCaptureDevice SelectedCam; //From where we will take image
System.Timers.Timer tim;
Thread t;
bool isNewFrame = false;
VideoFileWriter writer;
public Form1()
{
InitializeComponent();
tim = new System.Timers.Timer(10000);
tim.Elapsed += new System.Timers.ElapsedEventHandler(tim_Elapsed);
t = new Thread(saveVideo);
}
void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (isRecord)
{
writer.Close();
isRecord = false;
}
}
private void Form1_Load(object sender, EventArgs e)
{
ListOfCams = new FilterInfoCollection(FilterCategory.VideoInputDevice);
if (ListOfCams.Count == 0)
return;
comboBox1.Items.Clear();
foreach (FilterInfo Cam in ListOfCams)
{
comboBox1.Items.Add(Cam.Name);
}
}
private void StopCamera()
{
SelectedCam.SignalToStop();
SelectedCam.Stop();
}
bool isRecord = false;
private void Start_Click(object sender, EventArgs e)
{
if (comboBox1.Text == string.Empty)
return;
SelectedCam = new VideoCaptureDevice(ListOfCams[comboBox1.SelectedIndex].MonikerString);
SelectedCam.NewFrame += new NewFrameEventHandler(SelectedCam_NewFrame);
SelectedCam.Start();
}
Bitmap image;
void SelectedCam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
image = (Bitmap)eventArgs.Frame.Clone();
isNewFrame = true;
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
StopCamera();
}
private void Stop_Click(object sender, EventArgs e)
{
StopCamera();
}
private void btnRecord_Click(object sender, EventArgs e)
{
tim.Start();
if (!isRecord)
{
writer = new VideoFileWriter();
writer.Open(#"C:/code-bude_test_video.mp4", 640, 480, 25, VideoCodec.MPEG4,10000);
}
isRecord = !isRecord;
if (isRecord)
t.Start();
}
void saveVideo()
{
while (isRecord)
{
if (isNewFrame)
{
writer.WriteVideoFrame(image);
isNewFrame = false;
}
}
}
}
}
You have multi-threading issues in your code. You can't write to shared variables like that and expect it to synchronize.
You have three threads: user interface, streaming and saving. (SelectedCam_NewFrame runs in the AForge streaming thread). Make a list of all variables that are accessed in at least two threads (isRecord, isNewFrame, etc) and add proper synchronization.
You can check this very good reference on threading in C#.
Note that even with synchronization, you may miss frames if your writer thread is busy while several images arrive. What you might want to do is collect the frames produced by the camera in a queue and consume that queue in the writer thread. Check the producer/consumer patterns.

SendKeys GUI Bug

I've made this program in C#:
namespace Spammer
{
public partial class Form1 : Form
{
int delay, y = 1;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
delay = int.Parse(textBox2.Text);
timer1.Interval = delay;
timer1.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Enabled = false;
}
private void timer1_Tick(object sender, EventArgs e)
{
String textt = textBox1.Text;
SendKeys.SendWait(textt);
}
}
}
It works fine most of the time, and it can really send keys quickly.
But when I insert a delay of, for example, 10 MS, it's very hard to click the "Stop" button to stop it. The only way to stop the sending is to close the program and I don't want to do that.
Is there anyway I can send keys very quickly, like 5-10 MS, without it impairing my ability to press the buttons inside the program? I can't click while it's sending quickly...
The problem is that you're using SendWait. That will wait for the target application to respond - and while that's happening, your application won't be able to respond to user input. If you use Send instead of SendWait, your UI thread won't be blocked waiting for the key press to be processed.
I was able to reproduce the issue. The app is sending a keystroke every 10 milliseconds. To me, this is not at all surprising that the app is causing freezes. A keystroke every 10 milliseconds is quite a barrage to the active App. Threading is not going to help. Why is this behavior surprising?
In other words, I don't expect things to work out well when I overload the message pump.
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Spammer//your own namesapce
{
public partial class Form1 : Form
{
int delayInMilliseconds, y = 1;
private Timer timer1;
public Form1()
{
InitializeComponent();
//StartTimerWithThreading();
SetupTimer();
}
void StartTimerWithThreading()
{
Task.Factory.StartNew(() =>
{
SetupTimer();
});
}
void SetupTimer()
{
timer1 = new Timer();//Assume system.windows.forms.timer
textBox2.Text = "10";//new delay
timer1.Tick += timer1_Tick;//handler
}
private void button1_Click(object sender, EventArgs e)
{
delayInMilliseconds = int.Parse(textBox2.Text);
timer1.Interval = delayInMilliseconds;
timer1.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Enabled = false;
}
private void timer1_Tick(object sender, EventArgs e)
{
String textt = textBox1.Text;
SendKeys.SendWait(textt);
}
}
}
The simple solution is instead of adding code to a Click event handler for your button, we need a MouseDown event handler:
//MouseDown event handler for the button2
private void button2_MouseDown(object sender, EventArgs e) {
timer1.Enabled = false;
}
Or you can keep using the Click event handler but we send the key only when the MouseButtons is not Left like this:
private void timer1_Tick(object sender, EventArgs e) {
String textt = textBox1.Text;
if(MouseButtons != MouseButtons.Left) SendKeys.Send(textt);
}
//then you can freely click your button to stop it.

Categories

Resources