|
You could rewrite the entire component and code it as you wish. There is publicly available source code available here[^] that can be easily adapted.
The easiest way however would be to subclass the existing component and add a readonly property as below:
using System;
using System.ComponentModel;
using System.Windows.Forms;
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
CustomBackgroundWorker bgw = new CustomBackgroundWorker();
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
bgw.RunWorkerAsync("Test");
}
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
CustomBackgroundWorker bgw = sender as CustomBackgroundWorker;
if (bgw != null && bgw.Argument != null)
{
MessageBox.Show((string)bgw.Argument);
}
}
}
public class CustomBackgroundWorker : BackgroundWorker
{
private object argument;
public new void RunWorkerAsync(object argument)
{
this.argument = argument;
base.RunWorkerAsync(argument);
}
public object Argument
{
get { return argument; }
}
}
|
|
|
|
|
Looking into the implementation in a little more detail, the reason you can't access Result if an exception is thrown is RunWorkerCompletedEventArgs derives from AsyncCompletedEventArgs . The RunWorkerCompletedEventArgs inplementation of Result is:
public object Result {
get
{
base.RaiseExceptionIfNecessary();
return result;
}
} and the AsyncCompletedEventArgs.RaiseExceptionIfNecessary is:
protected void RaiseExceptionIfNecessary()
{
if (Error != null)
{
throw new TargetInvocationException(SR.GetString(SR.Async_ExceptionOccurred), Error);
}
else if (Cancelled)
{
throw new InvalidOperationException(SR.GetString(SR.Async_OperationCancelled));
}
} This doesn't solve your issue - but now you can see why it exists, and what you would need to change if you wanted to implement your own BackgroundWorker where Result is always available.
|
|
|
|
|
On reflection, I agree with Luc in his comment above that Argument should be available in all the event handlers and not really a property of the BackgroundWorker as it was in my simple first suggestion.
I figured I could make use of this myself so I've coded a new CustomBackgroundWorker and needed event args classes. I figured I'd share it as a Tip/Trick here[^].
|
|
|
|
|
I have more comments on BGW, e.g. why do we need to set WorkerReportsProgress and WorkerSupportsCancellation true to start using those features?
And why do its events not offer a sender object, as Controls do? so several BGW could easily share an event handler.
And why do BGWs not have a Tag property? maybe everything should have one, maybe not very OOish, but often very useful?
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that. All Toronto weekends should be extremely wet until we get it automated in regular forums, not just QA.
|
|
|
|
|
Luc Pattyn wrote: why do we need to set WorkerReportsProgress and WorkerSupportsCancellation true
Once again I agree, I made a GenericBackgroundWorker[^] some time ago and that is one of the things I addressed there by setting the fields to true in the constructor. Check out this section[^].
Luc Pattyn wrote: And why do its events not offer a sender object
They do - I've just checked!
Luc Pattyn wrote: why do BGWs not have a Tag property
Easily added, although it would need to have locks applied as it's almost guaranteed to be accessed from another thread.
|
|
|
|
|
DaveyM69 wrote: They do
My mistake. So the "argument" problem could have been handled with a dictionary technique (and all its pitfalls).
DaveyM69 wrote: (Tag property...) would need to have locks applied
That depends on how it gets used, as usual. Locking should be considered, and when necessary, implemented at the highest possible level.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that. All Toronto weekends should be extremely wet until we get it automated in regular forums, not just QA.
|
|
|
|
|
I am wondering if it is possbile to show multiple line for this param name "searchPattern" in the ///summary section. (Documentation explaining about the method and its parameters.
I mean to show as this in 2 lines.
For all files, use "*.*".
For hex files only, use "*.hex"
Instead of on one line.
For all files, use "*.*". For hex files only, use "*.hex"
<code snippet below>
/// <summary>
/// Gets the list of filenames in a certain directory path.
/// </summary>
/// <param name="path">Directory path</param>
/// <param name="searchPattern">For all files, use "*.*". For hex files only, use "*.hex"</param>
/// <returns> List of filenames in a directory path.
/// </returns>
public string[] GetFilenamesInDirectory(string path, string searchPattern)
{
....
}
|
|
|
|
|
Try:
/// <param name="searchPattern">For all files, use "*.*".<br/>For hex files only, use "*.hex"</param>
Modified: just realised you might have meant like this:
/// <param name="searchPattern">
/// For all files, use "*.*".
/// For hex files only, use "*.hex"
///</param>
|
|
|
|
|
Try this:
There are a set of pre-defined tags that one can use why doing XML style comments. Place a " < " and VS will display them to you."No matter how many fish in the sea; it will be so empty without me." - From song "Without me" by Eminem
|
|
|
|
|
This is what I did and it did work!
/// <param name="searchPattern">For all files, use "*.*".<para/> For hex files only, use "*.hex"</param>
Thanks for the help!
|
|
|
|
|
Hi,
I cant figure out how to switch my customcontrols when clicking on a menubar-button.
I have a MainWindow containing the following XAML:
<DockPanel x:Name="MainWindow">
<Menu Name="dropDownMenu"
DockPanel.Dock="Top">
<MenuItem Name="dropDownPage1" Header="File">
<MenuItem Header="Page1" Click="dropDown_Page1"/>
</MenuItem>
<MenuItem Name="dropDownPage2" Header="File">
<MenuItem Header="Page2" Click="dropDown_Page2"/>
</MenuItem>
</Menu>
<Grid Name="gridMainContent" DockPanel.Dock="Top">
<TextBlock>placeholder main content</TextBlock>
</Grid>
<Grid Name="gridStatusBar" DockPanel.Dock="Bottom">
<TextBlock>placeholder statusbar</TextBlock>
</Grid>
</DockPanel>
The task is when clicking on one menubutton i.e. "dropDown_Page1", changing the content of the grid "gridMainContent".
Is there a way to place customcontrols into a grid without code in any *.cs File ? It would be wonderfull if somebody could help me on this.
Cause I´m new to WPF, I welcome you to show me other ways of doing this!
Thx! PingOfDeath
|
|
|
|
|
There is a WPF forum at CP. It would be better if you post there. "No matter how many fish in the sea; it will be so empty without me." - From song "Without me" by Eminem
|
|
|
|
|
Hi, I wrote some code for two modems: one, must send some string and another must answer the call and receive the string. My receiver modem is a D-Link voice-modem which has COM port, and the sender modem is a NetForce usb2.0 data-modem. Two modems are connected to two different computers and each one has a phone line. I first run the receiver's code and then the sender's code. Here's the code for each of them and log files:
The receiver modem's code:
SerialPort sp = new SerialPort("COM1");
private void Form1_Load(object sender, EventArgs e)
{
sp.NewLine = "\r\n";
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.DtrEnable = true;
sp.WriteBufferSize = 1024;
sp.Open();
sp.WriteLine("ATE0");
sp.BaseStream.Flush();
sp.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(sp_DataReceived);
}
void sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string str;
str = sp.ReadLine();
if (str == "RING")
{
sp.WriteLine("ATA");
sp.BaseStream.Flush();
}
System.IO.File.AppendAllText("c:\\log_receiver.txt", str + "\r\n");
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
sp.Close();
}
and its log file(log_receiver.txt):
OK
RING
CONNECT 9600
And sender's code:
SerialPort sp = new SerialPort("COM8");
private void Form1_Load(object sender, EventArgs e)
{
sp.NewLine = "\r\n";
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.DtrEnable = true;
sp.WriteBufferSize = 1024;
sp.Open();
sp.WriteLine("ATE0");
sp.WriteLine("ATDT6632");
sp.BaseStream.Flush();
sp.WriteLine("My string to be sent");
sp.BaseStream.Flush();
sp.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(sp_DataReceived);
}
void sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string str;
str = sp.ReadLine();
File.AppendAllText("C:\\log_sender.txt", str + "\r\n");
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
sp.Close();
}
and the sender's log file(log_sender.txt);
ATE0
OK
NO CARRIER
I have read all the commands of the Hayes AT commands, but there were no tutorial about how to use the commands(I know that using commands may differ in some modems). I wanted to know that where's the problem of my code and does anyone have an idea about using AT commands in order to send and receive data between modems?
|
|
|
|
|
The "NO CARRIER" message indicates that there is no connection to the telephone line. Maybe you need to check your circuitry, or whether the receiver hangs up after getting the "RING" message. txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
so, why one of the modems returns CONNECT 9600 message?!
|
|
|
|
|
saeidfarahi wrote: so, why one of the modems returns CONNECT 9600 message?
Sorry, no idea, you need to check that your program is not causing a hang-up, or that there is no problem in the modem.txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
I created a custom timer class (MyTimer). The class is basicaly just a wrapper that internaly uses System.Threading.Timer. Class MyTimer will be used in a windows service app. Since the Timer class signals it events on the background thread, I am using Dispatcher.Invoke to marshal the requests to the current thread. Below is the event handler for the internaly used System.Threading.Timer.
private void timer_Elapsed(object state)
{
if (Dispatcher.CurrentDispatcher != _dispatcher)
{
_dispatcher.Invoke(
new System.Threading.ThreadStart(delegate
{
onTick();
}), DispatcherPriority.Send);
}
else
{
onTick();
}
}
private void onTick()
{
if (Tick != null)
{
Tick(this, new EventArgs());
}
}
The problem is that in some casses the _dispatcher.Thread is in stopped or WaitSleepJoin state, and the onTick() method doesn't execute. Does anybody has a solution to this problem? Any ideas will be appreciated.
Urošmodified on Friday, February 12, 2010 11:29 AM
|
|
|
|
|
Please read this[^]
Look at #3, "Hi" is not a descriptive subject line and is why your question is being ignored. I know the language. I've read a book. - _Madmatt
|
|
|
|
|
Thanks for the warning, it was a honest mistake.
Uros
|
|
|
|
|
Is there a tool that would help me examine the application domains in a running process that hosts the .NET runtime (BizTalk for instance)? Or the DLL's loaded by the said process?
|
|
|
|
|
In order to get the Dlls loaded by a process, you can make use of Process.Modules property. Not sure about getting the list of AppDomains in a process. In case you know the AppDomain , AppDomain.GetAssemblies method would do same for you."No matter how many fish in the sea; it will be so empty without me." - From song "Without me" by Eminem
|
|
|
|
|
Thank you for your answer. I will start with that, that should be enough.
I wanted to do this because you can instruct BizTalk to load specific assemblies into named domains and not to unload those domains when idle.
|
|
|
|
|
You can also use the Fusion Log Viewer, it's installed with most visual studio installs, if not it is easily downloaded from Microsoft Downloads. Open up a visual studio command prompt, and type FUSLOGVW. have this open whily you run your process, and it will log all the assembly binds that occur.
|
|
|
|
|
Hi i am trying to write a tree view control however have come accross difficulty in drawing the vertical lines.
The bellow method currently works by fining the cumulative height of the last branch it was in and then calls AmountToDeduct(nodes[i].Nodes) to reduce this to the correct height for the next line.
However this is very slow. Does anyone know a way i can simply not add nodeheight to the newLineFinishPoint if it is not needed apposed to taking away from the total heigh.
private Point PositionNodes(List<Node> nodes, Point point)
{
Point newStartPoint = new Point();
Point newFinishPoint = new Point();
newStartPoint = point;
int nodeHeight = nodes[0].Size.Height;
for(int i = 0; i < nodes.Count; i++)
{
nodes[i].Location = point;
point.Y += nodeHeight;
if (nodes[i].Nodes.Count > 0 && nodes[i].Expanded)
{
point.Y = PositionNodes(nodes[i].Nodes, new Point(point.X + m_xIndentation, point.Y)).Y;
}
newFinishPoint = point;
newFinishPoint.Y -= (int)(nodes[0].Size.Height * 0.5);
if (nodes.Count == 1 && nodes[i].Expanded)
{
newFinishPoint.Y -= AmountToDeduct(nodes[i].Nodes);
}
m_linePoints.Add(newStartPoint);
m_linePoints.Add(newFinishPoint);
}
return point;
}
Thanks in advance
|
|
|
|
|
hi there,
I need to read a text file, but i want to read only the first 5 lines.
please help me
Thanx
|
|
|
|