Is there any way to detect if ListView or CollectionView is scrolling by user and not from ScrollTo method?
I am using ScrollTo as the example below:
colViewCategories.ScrollTo(categoryItem, null, ScrollToPosition.Center, true);
Or if i can disable Scrolled Event till ScrollTo Method will stop to scroll.
I finally found my answer.
bool scrollAnimationIsRaised=false;
int previousindex = 0;
private System.Timers.Timer tmr = new System.Timers.Timer();
private void InitTimer
{
tmr.Interval = 500; //waiting 500ms after scrollTo has Stop for not having conflicts
tmr.Elapsed += Tmr_Elapsed;
}
private void ButtonClick(object sender, EventArgs e)
{
scrollAnimationIsRaised = true;
listview.ScrollTo(50);
}
private void ListviewItems_Scrolled(object sender, ItemsViewScrolledEventArgs e)
{
if(scrollAnimationIsRaised)
{
//ScrollToEvent Is Fired
if (e.LastVisibleItemIndex == previousindex)
tmr.Start();
previousindex = e.LastVisibleItemIndex;
}
else
{
//ScrollTo event has finished
}
}
private void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
tmr.Stop();
scrollAnimationIsRaised = false;
}
Related
I want to run a progress bar on a form through the use of a timer.
I have tried multiple ways and have not been able to get it to work.
I hope someone here can help me with this.
private void SplashScreen_Load(object sender, EventArgs e)
{
splashScreenTimer.Enabled = true;
splashScreenTimer.Start();
splashScreenTimer.Interval = 1000;
progressBar.Maximum = 100;
splashScreenTimer.Tick += new EventHandler(timer1_Tick);
}
private void timer_Tick(object sender, EventArgs e)
{
if (progressBar.Value != 10)
{
progressBar.Value++;
}
else
{
splashScreenTimer.Stop();
}
}
you are assigning event_handler like
splashScreenTimer.Tick += new EventHandler(timer1_Tick);
and you are changing the progressBar value in
private void timer_Tick(object sender, EventArgs e)
{
if (progressBar.Value != 10)
{
progressBar.Value++;
}
else
{
splashScreenTimer.Stop();
}
}
change event handler to
splashScreenTimer.Tick += new EventHandler(timer_Tick);
or move codes to the other event handler timer1_Tick which should be in your form
For running the progressBar full in 4 seconds you can do like this
private void Form1_Load(object sender, EventArgs e)
{
splashScreenTimer.Enabled = true;
splashScreenTimer.Start();
splashScreenTimer.Interval = 30;
progressBar.Maximum = 100;
splashScreenTimer.Tick += new EventHandler(timer_Tick);
}
int waitingTime = 0;
private void timer_Tick(object sender, EventArgs e)
{
if (progressBar.Value < 100)
{
progressBar.Value++;
}
else
{
if (waitingTime++ > 35)
this.Close();
}
}
I am new in C#. I found some code which work on progressbar. What is does, when someone click on button start btnStartAsyncOperation_Click the progress bar starts increasing and when btnCancel_Click is pressed it cancel the operation. Here is the code
namespace BackgroundWorkerSample
{
public partial class Form1 : Form
{
BackgroundWorker m_oWorker;
public Form1()
{
InitializeComponent();
m_oWorker = new BackgroundWorker();
m_oWorker.DoWork += new DoWorkEventHandler(m_oWorker_DoWork);
m_oWorker.ProgressChanged += new ProgressChangedEventHandler(m_oWorker_ProgressChanged);
m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(abcd);
m_oWorker.WorkerReportsProgress = true;
m_oWorker.WorkerSupportsCancellation = true;
}
void abcd(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
lblStatus.Text = "Task Cancelled.";
}
else if (e.Error != null)
{
lblStatus.Text = "Error while performing background operation.";
}
else
{
lblStatus.Text = "Task Completed...";
}
btnStartAsyncOperation.Enabled = true;
btnCancel.Enabled = false;
}
void m_oWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
}
void m_oWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(100);
m_oWorker.ReportProgress(i);
if (m_oWorker.CancellationPending)
{
e.Cancel = true;
m_oWorker.ReportProgress(0);
return;
}
}
//Report 100% completion on operation completed
m_oWorker.ReportProgress(100);
}
private void btnStartAsyncOperation_Click(object sender, EventArgs e)
{
btnStartAsyncOperation.Enabled = false;
btnCancel.Enabled = true;
//Start the async operation here
m_oWorker.RunWorkerAsync();
}
private void btnCancel_Click(object sender, EventArgs e)
{
if (m_oWorker.IsBusy)
{
//Stop/Cancel the async operation here
m_oWorker.CancelAsync();
}
}
private void progressBar1_Click(object sender, EventArgs e)
{
}
private void lblStatus_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}
Now I added 2 more button, button1 to pause and button2 to resume. Since I could not find any method to resume, I had to use CancelAsync() function when I press pause and I keep the value of progress bar in a global variable. Then when I press resume I start the progress bar again using RunWorkerAsync. But the problem is, I can not send the value of global variable in this function so it start from 0 progress.
I tried to use thread.sleep(infinite time here) when someone press pause and then stop the thread when someone press resume. Still the problem is, I can not press any button in this situation. Still if I enable button they don't work.
Please give me some solution.
You could try having your own variable, i.e
bool isPaused = false;
When someone clicks your pause button...
isPaused = true;
And set it to false when someone clicks resume. Finally, in your for loop in your doWork method, make it wait until that variable is false.
while (isPaused)
{
Thread.Sleep(100);
}
Let me know how this works out for you.
I have a listboxcontrol where I'm inserting Log text
and display always the last lines
listBoxControl1.SelectedIndex = listBoxControl1.Items.Count - 1;
but when the user scolls up/down the list, I wish to maintain the user's scroll position
,
a condition to cancel the code above
I tried with MouseUp / MouseDown but these event won't fire on clicking the ScrollBar
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
listBoxControl1.Items.Add(e.UserState);
if (!mouseDown) // this is not working !!
listBoxControl1.SelectedIndex = listBoxControl1.Items.Count - 1;
}
Thanks
I believe you can use the following approach:
SubscribeScrollEvent(listBoxControl1); // Before start items adding
bw.RunWorkerAsync();
//...
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
UnsubscribeScrollEvent(listBoxControl1); // After items adding complete
}
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) {
listBoxControl1.Items.Add(e.ProgressPercentage);
if(!userScrollPerformed)
listBoxControl1.SelectedIndex = listBoxControl1.Items.Count - 1;
}
//...
void SubscribeScrollEvent(ListBoxControl listBox) {
var hScroll = listBox.Controls[0] as DevExpress.XtraEditors.HScrollBar;
var vScroll = listBox.Controls[1] as DevExpress.XtraEditors.VScrollBar;
vScroll.Scroll += ListBox_Scroll;
hScroll.Scroll += ListBox_Scroll;
}
void UnubscribeScrollEvent(ListBoxControl listBox) {
var hScroll = listBox.Controls[0] as DevExpress.XtraEditors.HScrollBar;
var vScroll = listBox.Controls[1] as DevExpress.XtraEditors.VScrollBar;
vScroll.Scroll -= ListBox_Scroll;
hScroll.Scroll -= ListBox_Scroll;
}
bool userScrollPerformed;
void ListBox_Scroll(object sender, ScrollEventArgs e) {
if(e.Type == ScrollEventType.ThumbTrack)
userScrollPerformed = true; // set a flag
}
I have a WPF form which runs a background operation with progress bar. but the problem is that;
when the operation is completed, the progress bar is still running. I mean it shows like the operation is in progress.
how can I stop that? here is my whole code;
System.ComponentModel.BackgroundWorker mWorker;
private void button1_Click(object sender, RoutedEventArgs e) {
mWorker = new System.ComponentModel.BackgroundWorker();
mWorker.DoWork +=new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
mWorker.ProgressChanged +=new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
mWorker.WorkerReportsProgress = true;
mWorker.WorkerSupportsCancellation = true;
mWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
mWorker.RunWorkerAsync();
while (pbProcessing.Value != 100) {
if (!mWorker.CancellationPending) {
try {
pbProcessing.Value = (pbProcessing.Value + 0.01) % 100;
} catch (System.Exception ex) {
// No action required
}
} else {
MessageBox.Show(this, "Process cancelled", "Cancel Process", MessageBoxButton.OK);
break;
}
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
new System.Threading.ThreadStart(delegate { }));
}
}
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
// Do your work here, its on seperate thread
System.Threading.Thread.Sleep(10000);
}
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) {
pbProcessing.Value = e.ProgressPercentage;
}
private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) {
// Stop Progressbar updatation
Window1 w = new Window1();
w.Browser.Navigate(new Uri("http://stackoverflow.com"));
w.Show();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
if (mWorker != null) {
if (mWorker.IsBusy) {
mWorker.CancelAsync();
}
}
}
If you want to hide the progressbar after the work is done, set its Visibility property to Visibility.Hidden. If you just want to reset it to its initial state, set it's Value to 0 (or to pbProgressing.Minimum, if you changed that from its default value).
As a side note, your code doesn't really make sense: Instead of continuously changing pbProcessing.Value in the button event handler (which is completely useless, since no UI updates are performed until the button event handler has completed), you should only change the value in ProgressChanged. I.e., your code should look something like this:
System.ComponentModel.BackgroundWorker mWorker;
private void button1_Click(object sender, RoutedEventArgs e) {
mWorker = new System.ComponentModel.BackgroundWorker();
mWorker.DoWork +=new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
mWorker.ProgressChanged +=new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
mWorker.WorkerReportsProgress = true;
mWorker.WorkerSupportsCancellation = true;
mWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
mWorker.RunWorkerAsync();
// Don't do anything else here
}
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
for (int i = 1; i < 100; i++) {
mWorker.ReportProgress(i);
// Do some part of the work
System.Threading.Thread.Sleep(100);
// Check if the user wants to abort
if (mWorker.CancellationPending) {
e.Cancel = true;
return;
}
}
mWorker.ReportProgress(100); // Done
}
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) {
pbProcessing.Value = e.ProgressPercentage;
}
private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) {
// Stop Progressbar updatation
Window1 w = new Window1();
w.Browser.Navigate(new Uri("http://stackoverflow.com"));
w.Show();
// Check the result
if (e.Cancelled) {
// show the message box that the task has been canceled
}
// Reset Progress bar
pbProcessing.Value = 0;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
if (mWorker != null) {
if (mWorker.IsBusy) {
mWorker.CancelAsync();
}
}
}
i have both the events cellclick and celldoubleclick for a datagridview in my window forms application.
The problem is that when i double click , only the cellclick event triggers, as it cannot detemine if its single click or double click.
i searched for this and found that timers could be the solution..but how to do that ?
plz help
You probably ought to try to find out why double-click isn't getting fired. Answering your question: you'll indeed need a timer whose Interval you set to the double-click time:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
timer1.Interval = SystemInformation.DoubleClickTime;
timer1.Tick += delegate { timer1.Enabled = false; };
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
if (timer1.Enabled) {
timer1.Enabled = false;
// Do double-click stuff
//...
}
else {
timer1.Enabled = true;
// Do single-click stuff
//...
}
}
}
I established a little solution for this:
add timer in your form
public Form1()
{
timer1.Interval = SystemInformation.DoubleClickTime;
}
bool double_click = false;
//
DataGridViewCellEventArgs sendedEvent = null;
private void DatagridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
double_click = true;
sendedEvent = e;
}
private void DatagridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
sendedEvent = e;
//
timer1.Enabled = true;
//
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (!double_click)
{
// DO your simple click stuff and USE sendedEvent if needed
}
else
{
double_click = false;
// DO your Doubleclick stuff and USE sendedEvent if needed
}
timer1.Stop();
timer1.Enabled = false;
}
Hope this will help ^^