|
Hi everybody!
I'm new on C# programming. I have a main form in my Windows applications that contains other form as a Explorer of folders. I don't want to allow to drag the Explorer form (FrmExplorer). FrmExplorer has a TreeView. I have been looking for information about it and have written the following code:
public partial class FrmExplorer : Form
{
public FrmExplorer(string fileName)
{
InitializeComponent();
//To cancel dragging the form
this.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.FrmExplorer_CancelDrag);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.FrmExplorer_EnterDrag);
this.DragOver += new System.Windows.Forms.DragEventHandler(FrmExplorer_DragOver);
this.AllowDrop = false;
}
private void FrmExplorer_CancelDrag(object sender, QueryContinueDragEventArgs e)
{
e.Action = DragAction.Cancel;
}
private void FrmExplorer_EnterDrag(object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect = DragDropEffects.None;
}
private void FrmExplorer_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{
// Determine whether string data exists in the drop data. If not, then
// the drop effect reflects that the drop cannot occur.
if (!e.Data.GetDataPresent(typeof(System.String)))
{
e.Effect = DragDropEffects.None;
return;
}
}
}
I have set the method FrmExplorer_CancelDrag in FrmExplorer Properties in the event QueryContinueDrag. But I still cannot reach the method FrmExplorer_CancelDrag when dragging the form to cancel that action.
Does anybody can help me to know what I'm doing wrong or what is it missing?
Thanks a lot in advance,
Elvia
|
|
|
|
|
Hi guys
I'm having some difficulty with the System.Threading.ManualResetEvent.
My function is listed below. Excuse the relatively large function; scroll down towards the end and you'll see the line I'm having trouble with.
private static bool WaitForCompletionOrTimerExpiration(Function method, int timeout)
{
using (ManualResetEvent threadWaitHandle = new ManualResetEvent(false))
{
bool hasFinishedExecutingMethod = false;
int hasSignalled = 0;
TimerCallback timerCallback = delegate(object state)
{
int originalValueOfHasSignalled = Interlocked.CompareExchange(ref hasSignalled, 1, 0);
if (originalValueOfHasSignalled == 0)
{
threadWaitHandle.Set();
}
};
Exception methodException = null;
WaitCallback threadPoolMethod = delegate(object state)
{
try
{
method();
}
finally
{
int originalValueOfHasSignalled = Interlocked.CompareExchange(ref hasSignalled, 1, 0);
if (originalValueOfHasSignalled == 0)
{
hasFinishedExecutingMethod = true;
threadWaitHandle.Set();
}
}
};
using (Timer timer = new Timer(timerCallback, null, timeout, Timeout.Infinite))
{
ThreadPool.QueueUserWorkItem(threadPoolMethod);
threadWaitHandle.WaitOne();
}
return hasFinishedExecutingMethod;
}
}
Notice the WaitOne() call; sometimes this call blocks forever! In what circumstance will thread WaitOne() call block forever?
Tech, life, family, faith: Give me a visit.
I'm currently blogging about: Islamic Domination: Coming to a Jewish state near you!
The apostle Paul, modernly speaking: Epistles of Paul
Judah Himango
|
|
|
|
|
Judah Himango wrote: threadWaitHandle.Set();
Shouldn't that be Reset?
Here is what I gather:
- you start at a off state (shouldnt that be on?)
- the timer starts before the ThreadPool submission
- the ThreadPool start time is normally slow
Why not use the WaitOne(Int32, Boolean) overload? You wouldnt have to use a timer then.
Hope it helps
|
|
|
|
|
I'm not all too familiar with the WaitHandle; so you'll have to pardon my lack of knowledge there.
Before you posted I realized I can use the WaitOne overload that takes a time period which to wait, thus making my timer code redundant. So I've removed the timer code and opted to use the WaitOne overload.
However, you brought up something I'm not understanding. Should it be Reset instead of Set? I'm starting with an off state and switching to an on state. You're saying that's incorrect usage? I guess I'm not understanding why it would matter either way, as Set() seems to signal the waiting thread correctly.
Tech, life, family, faith: Give me a visit.
I'm currently blogging about: Islamic Domination: Coming to a Jewish state near you!
The apostle Paul, modernly speaking: Epistles of Paul
Judah Himango
|
|
|
|
|
I just looked at some of my code I used it before, it appears Set() is correct .
The only difference I can see is that I explicitly call Reset() before starting the thread. Everything else seems the same. Perhaps that is the magic required Hope it works!
PS: If you want to, I can mail you the code, its part of xacc.ide. (if u have the source, Build\Action.cs:1005).
|
|
|
|
|
|
|
I'm having problems getting my head around raising event on the UI thread, and haven't been able to find an example for my particular situation. I've written a homespun class that exposes an integer property, and raises an event whenever it changes:
public class Engine<br />
{<br />
public event EventHandler ProgressChanged;<br />
private int progress;<br />
<br />
public Engine ()<br />
{<br />
progress = 0;<br />
}<br />
<br />
public int Progress<br />
{ get { return progress; } }<br />
<br />
public void Run ()<br />
{<br />
for(int index = 0; index < 100; index++)<br />
{<br />
Thread.Sleep(1000);<br />
progress++;<br />
if(ProgressChanged != null)<br />
ProgressChanged(this,new EventArgs());<br />
}<br />
}<br />
}
I want to bind this property to a ProgressBar in my UI.
Engine obj = new Engine();<br />
progressBar.DataBindings.Add("Value",obj,"Progress");<br />
Thread thread = new Thread(new ThreadStart(obj.Run));<br />
thread.Start();
But of course I can't update the ProgressBar from my worker thread, that's something I understand and accept. I think I should be using BeginInvoke to raise the event, but I'm lost as to how to do this.
Any ideas? Thanks in advance, Iain.
|
|
|
|
|
First of all, you can update your progress bar from a worker thread. Second of all, an event is not thrown when you do a ++ on progress.
Change your property to something like this:
public int Progress {
get { return progress; }
set {
progress = value;
if (ProgressChanged != null)
ProgressChanged(this, new EventArgs());
}
}
Then you could write a Progress++ in your code and the event will fire.
But what you're really trying to do is tell your progress bar to increment. What I do for this is add this delegate to my form class:
delegate void ProgressBarStep();
Then I have a method that's called by my worker thread:
private void WorkerThreadMethod()
{
...
ProgressBarStep progBarStep = delegate() { progressBar.PerformStep(); };
...
Invoke(progBarStep);
...
}
Notice that I use an anonymous method and call Invoke on the form itself. This will let you call methods on the main thread from another thread. Use the invoke inside your loop.
Hope that makes sense.
www.logifusion.com
-- modified at 12:06 Monday 22nd May, 2006
|
|
|
|
|
Thanks Dustin for your input.
My main issue, which I didn't expand on in my original post (apologies!) is that I don't know in advance which UI control or controls will be bound to my Engine object. As such I want to avoid completely, or as far as possible, directly calling methods on the UI controls. In fact I really want my Engine class to be generic so that I can use it in a number of places, and bind different UI controls to different Engine objects.
If you can offer any further advice I would really appreciate your input.
Thanks again, Iain.
|
|
|
|
|
One thing you can do is pass an object to the Engine class that allows the Engine to raise events on the UI thread.
Here's how you can do it:
using System.Threading;
public class Engine
{
public event EventHandler ProgressChanged;
private int progress;
private SynchronizationContext eventRaisingContext;
public Engine (SynchronizationContext uiContext)
{
this.eventRaisingContext = uiContext;
}
public int Progress
{ get { return progress; } }
public void Run ()
{
for(int index = 0; index < 100; index++)
{
Thread.Sleep(1000);
progress++;
RaiseEventOnCorrectThread();
}
}
}
private void RaiseEventOnCorrectThread()
{
eventRaisingContext.Post(RaiseEvent, null);
}
private void RaiseEvent(object state)
{
if(ProgressChanged != null)
ProgressChanged(this,new EventArgs());
}
}
And then in your UI code, just supply a synchronization context:
Engine obj = new Engine(System.Windows.Forms.WindowsFormsSynchronizationContext.Current);
progressBar.DataBindings.Add("Value",obj,"Progress");
Thread thread = new Thread(new ThreadStart(obj.Run));
thread.Start();
Tech, life, family, faith: Give me a visit.
I'm currently blogging about: Islamic Domination: Coming to a Jewish state near you!
The apostle Paul, modernly speaking: Epistles of Paul
Judah Himango
|
|
|
|
|
Thanks Judah for your input.
I think I can see how passing in a context allows me to call methods on an object created in a different thread. However my main issue, which I didn't expand on in my original post (apologies!) is that I don't know in advance which UI control or controls will be bound to my Engine object. So with this context approach I would need some way for each control to specify it's context. Or would all the UI controls be created in the same thread, and therefore have the same context?
I really want my Engine class to be generic so that I can use it in a number of places, and bind different UI controls to different Engine objects. I'd anticipated that I'd need to use BeginInvoke on my ProgressChanged method. If you can offer any further advice I would really appreciate your input.
Thanks again, Iain.
|
|
|
|
|
In a typical situation, all--or virtually all--UI controls will be created from the same thread. Thus, the solution posted should work fine.
If you happen to have controls created on different threads, you can still make this work:
Engine engine = new Engine(WindowsFormsSynchronizationContext.Current);
engine.RunOnSeperateThread();
Engine engine = new Engine(WindowsFormsSynchronizationContext.Current);
engine.RunOnSeperateThread();
This should work as well.
If the Engine class is *always* created on the UI, but the Run() method is *always* spawning a background thread to do the real work, you might want to investigate the System.ComponentModel.BackgroundWorker. The BackgroundWorker is nice as it lets you do the following:
worker.DoWork += someMethodToRunOnBackground;
worker.ProgressChanged += someMethodToRunOnUIThreadWhenProgressReported;
worker.RunWorkerCompleted += someMethodToRunOnUIThreadWhenFinished;
worker.RunWorkerAsync();
This way is quite generic and pretty straightforward. Your DoWork handler will get run on a background thread. Your ProgressChanged handler will get called on your UI thread. Your RunWorkerCompleted will get called on the UI thread. Nice stuff, I suggest you check it out if you haven't already. You could use the BackgroundWorker internally in your Engine class if you wanted to retain existing code.
Tech, life, family, faith: Give me a visit.
I'm currently blogging about: Islamic Domination: Coming to a Jewish state near you!
The apostle Paul, modernly speaking: Epistles of Paul
Judah Himango
|
|
|
|
|
Hi all,
I need some articles/materials/presentation for the following topics
1. Thread synchronization
2. basics of Appdomain,STA,MTA
3. Thread Safety/Cross thread calling
4. XML handling reading/writing/encrypting xml
If anybody has plese share..
TIA
Srini
|
|
|
|
|
|
Thanks for ur reply.
Yes i did some search on codeproject and google. even i read some of the articles.but still i am not able understand the mentioned concepts. If you have something particularly that could explains the mentioned things please share.
Thanks
Srini
|
|
|
|
|
Hi,
I am trying to run a C# code to generate a dll file that I will need for a pocket PC appication. When I build the code, I am getting 107 errors that are similar to this one:
Error 1 The type or namespace name 'SymmetricAlgorithm' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\msolh\Desktop\Security\Security\Cryptography\RC4.cs 46 30 Security
For instance in this error I checked for 'SymmetricAlgorithm' and I found that it is part of mscorlib and namespace system.Security.cryptography. The library and the namespace are both included in my project but still it is giving me the same errors.
If you had this problem before, please help.
|
|
|
|
|
Do you compile your project for the compact framework? According to MSDN this class is supported only by the 2.0 version of the compact framework.
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Thanks,
The problem is solved it turned out that I was running a 1.0 version of compact framework.
But know I am stuck into another problem:
It turned out some of the classes I am using are not supported for windows mobile. I donot know how to subtitute them. One of the classes for example is:
DeriveBytes
|
|
|
|
|
msolh wrote: It turned out some of the classes I am using are not supported for windows mobile. I donot know how to subtitute them.
Yeah, that's unfortunately something you had to take care of while designing your app.
You only have the option to rewrite this class my yourself of find a substitute class which provides similar functionality.
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Is it possible to fill listview with an one or more dimensional array by using databinding method?
|
|
|
|
|
hi all,
is it possible to hide (and show) unwanted tabs when dealing with a specific tab ?
let's say i've a tabcontrol with 5 pages (first page is only required for a while) and with a button click i want to hide all other 4 pages ?
then i make them show again when i need them ?
|
|
|
|
|
If you are using VS2005, you can do it as follows:
create dynamic tabs array through code.
Create each tab and add to the tab list, when ever you need to hide you can stop loading those tabs.
Try and check, else i will give you sample code
|
|
|
|
|
I suppose the
TabControl1.TabPages(1).Visible = False Wont work in .Net Framework 1.1. As a work around you use
TabControl1.TabPages.Add() and TabControl1.TabPages.Remove() as when you require tab pages
|
|
|
|
|
yes,
hide and show or Visible =true or false properties are not available for TabPages, Only availble option is Remove and add again.
RemoveAt(...) and RemoveByKey(...) are availble and then we can add at any time.
Ravi
|
|
|
|