|
Hi,
Is there any support for graphs in .Net (simple bar, line and dot graphs)? Any examples to use will be good.
Gurpreet
|
|
|
|
|
Have a look at this article.
My signature "sucks" today
|
|
|
|
|
you can use microsoft chart control for graphs in dotnet applications
|
|
|
|
|
Yes. See this[^] link.
/ravi
|
|
|
|
|
protected virtual void Dispose(bool bDisposing)
{
if (bDisposing)
{
// No need to call the finalizer since we've now cleaned
// up the unmanaged memory
GC.SuppressFinalize(this);
}
if(this.m_pNativeObject != IntPtr.Zero)
{
// Call the DLL Export to dispose this class
DisposeNetworkImp(this.m_pNativeObject);
}
}
|
|
|
|
|
Shouldn't the DisposeNetworkImp IF and code go inside the if(bDisposing) block?
|
|
|
|
|
There might be a problem with the "Data Execution Prevention" (DEP). We had lots of problems with a third party component till we were told about that.
Just switch DEP off for a test. If that resolves the problem, you can also prevent DEP for your program by adding a post build action:
call "$(VS80COMNTOOLS)\vsvars32.bat"
editbin.exe /NXCOMPAT:NO "$(TargetPath)"
|
|
|
|
|
I found the error i was creating the object with diff class and trying to delete it with different class destructor the problem was in DLL only.
|
|
|
|
|
How to solve this problem?
System.Data.SqlClient.SqlException: Can not open 'User Management' in the request database. Login failed.
User 'HUIZHI-C02E58FC\liuhanpo' Login failed.
In System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
In System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
In System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
In System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
In System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnection owningObject)
In System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(String host, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, Int64 timerStart)
In System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)
In System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)
In System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
In System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
In System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
In System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
In System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
In System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
In System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
In System.Data.SqlClient.SqlConnection.Open()
In User Management.ChangestaffPwd.button5_Click(Object sender, EventArgs e) Location C:\Documents and Settings\liuhanpo\Desktop\User Management\ChangestaffPwd.cs:Line 137
In System.Windows.Forms.Control.OnClick(EventArgs e)
In System.Windows.Forms.Button.OnClick(EventArgs e)
In System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
In System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
In System.Windows.Forms.Control.WndProc(Message& m)
In System.Windows.Forms.ButtonBase.WndProc(Message& m)
In System.Windows.Forms.Button.WndProc(Message& m)
In System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
In System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
In System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
|
|
|
|
|
Make sure the credentials you are using are valid. Check for typos, uses SSMS to connect using the credentials.
If you are using a restored database you may need to drop and recreate the user in SQL Server.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I thought I had this down from asking this question before but I'm having issues with this once again.
What I am trying to do is load a picture from a database using the IDataReader (so I can read it byte by byte). Now I have this function in another class with events. So I have a ProgressChanged event and a Finished Event. Before calling these events I check if they are null and it still gives me this error
[5/23/2010 10:58:31 PM LoadPicture]: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'frmViewAsset'.
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at System.Windows.Forms.Control.Invoke(Delegate method)
at AssetMgmt.frmViewAsset.p_ProgressChanged(Int32 current, Int32 max, String c, String t) in C:\Applications\Windows Applications\AssetMgmt\AssetMgmt\frmViewAsset.cs:line 388
at AssetMgmt.LoadPicture.Load() in C:\Applications\Windows Applications\AssetMgmt\AssetMgmt\Operations\LoadPicture.cs:line 74
Now first you probably want to know what is line 388 on frmViewasset (this is the parent form). The code below is the event in the parent form.. the action it takes when the event is called from the LoadPicture class. The thing is I am "dispoing" of this event on the FormClosing and it still isn't working right.. givingme that error
private void p_ProgressChanged(int current, int max, string c, string t)
{
if (!this.IsDisposed)
{
Invoke((Action)(() =>
{
pbPicture.Maximum = max;
pbPicture.Value = current;
lbPicProgress.Text = string.Format("{0}MB / {1}MB", c, t);
}));
}
}
LoadPicture lp;
private void frmViewAsset_Load(object sender, EventArgs e)
{
lp = new LoadPicture(AssetID);
lp.ProgressChanged += new LoadPicture.ProgressDelegate(p_ProgressChanged);
lp.Finished += new LoadPicture.FinishedDelegate(p_Finished);
t4 = new Thread(new ThreadStart(PopulatePicture));
t4.Start();
}
private void PopulatePicture()
{
lp.Load();
}
private void frmViewAsset_FormClosing(object sender, FormClosingEventArgs e)
{
lp.Stop();
lp.Dispose();
}
So basicaly when the form loads it creates another thread that calls the lp.Load(). This begins the SQL Connection and reads byte by byte (or every 1024 bytes). Each time it loops it calls:
if (ProgressChanged != null)
ProgressChanged(blahblahblah);
So how come i'm c alilng my lp.Dispose() (which sets ProgressChanged = null) i still get this error when the user exits? I just can't figure it out
|
|
|
|
|
so what is in line 388?
and I'm afraid we need to see more code: the LoadPicture constructor, its Load method, and how its Progress and Finished events work. and can we see p_Finished()?
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I'm sorry I was nervous about putting taht much code in the first post. I know its not recommended..
Ok the LoadPicture Class:
class LoadPicture : IDisposable
{
public delegate void FinishedDelegate(Image img);
public delegate void ProgressDelegate(int current, int max, string c, string t);
public event FinishedDelegate Finished;
public event ProgressDelegate ProgressChanged;
string Tag;
bool stop;
public LoadPicture(string Tag)
{
this.Tag = Tag;
stop = false;
}
~LoadPicture()
{
ProgressChanged = null;
Finished = null;
}
public void Load()
{
SqlConnection conn = new SqlConnection(AssetConfig.ConnectionString);
SqlCommand cmd = new SqlCommand("SELECT Picture FROM Inventory_Pictures WHERE PictureID=@Tag", conn);
cmd.Parameters.AddWithValue("@Tag", Tag);
try
{
conn.Open();
SqlDataReader tmp = cmd.ExecuteReader();
if (tmp.HasRows)
{
tmp.Close();
IDataReader r = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
if (r != null)
{
r.Read();
long size = r.GetBytes(0, 0, null, 0, 0);
byte[] buffer = new byte[size];
int bufferSize = 1024;
int dataIndex = 0;
long bytesRead = 0;
while ((bytesRead < size) && ((size - bytesRead) > 1024))
{
if (stop)
break;
bytesRead += r.GetBytes(0, dataIndex, buffer, dataIndex, bufferSize);
dataIndex += 1024;
decimal FileSize = (Convert.ToDecimal(size) / 1024) / 1024;
decimal CurrentSize = (Convert.ToDecimal(bytesRead) / 1024) / 1024;
if (ProgressChanged != null)
ProgressChanged(dataIndex, Convert.ToInt32(size), Math.Round(CurrentSize, 2).ToString(), Math.Round(FileSize, 2).ToString());
}
if (!stop)
{
bytesRead += r.GetBytes(0, dataIndex, buffer, dataIndex, Convert.ToInt32((size - bytesRead)));
MemoryStream ms = new MemoryStream(buffer);
if (Finished != null)
Finished(Image.FromStream(ms));
ms.Close();
}
}
r.Close();
}
}
catch (Exception ex)
{
Error.WriteError(ErrorType.SQL, "LoadPicture", ex.ToString());
}
finally
{
if (conn != null)
{
conn.Close();
conn.Dispose();
}
if (cmd != null)
cmd.Dispose();
}
}
public void Stop()
{
stop = true;
}
public void Dispose()
{
System.GC.SuppressFinalize(true);
}
}
Here is frmViewAsset (some of it) and you notice how it initializes the events:
LoadPicture lp;
Thread t4;
private void frmViewAsset_Load(object sender, EventArgs e)
{
lp = new LoadPicture(AssetID);
lp.ProgressChanged += new LoadPicture.ProgressDelegate(p_ProgressChanged);
lp.Finished += new LoadPicture.FinishedDelegate(p_Finished);
t4 = new Thread(new ThreadStart(PopulatePicture));
t4.Start();
}
private void PopulatePicture()
{
lp.Load();
}
private void p_ProgressChanged(int current, int max, string c, string t)
{
if (!this.IsDisposed)
{
Invoke((Action)(() =>
{
pbPicture.Maximum = max;
pbPicture.Value = current;
lbPicProgress.Text = string.Format("{0}MB / {1}MB", c, t);
}));
}
}
private void p_Finished(Image img)
{
Invoke((Action)(() =>
{
picAsset.Image = img;
}));
}
private void frmViewAsset_FormClosing(object sender, FormClosingEventArgs e)
{
lp.Stop();
lp.Dispose();
}
You will see on the frmViewAsset I am calling lp.Stop(); which should be stopping the datareader from reading any further (breaking out of the while statement in the LoadPicture class). You also notice I call lp.Dispose() which should be setting both PRogressChanged and Finished events to null
I'm assuming that LoadPicture is having a hard time disposing before frmViewAsset can dispose (hints why it is still called). But why?!?!
FYI I have also tried this on form closing:
lp.ProgressChanged -= new LoadPicture.ProgressDelegate(p_ProgressChanged);
lp.Finished -= new LoadPicture.FinishedDelegate(p_Finished);
The ultimate goal is to load the picture by every 1024 bytes which allows me to display a progress bar and label showing 1.0MB out of 2.0MB (that kind of thing). All this works except if the user closing this form before it has finished loading the picture (which I need it to safely dipose / stop loading it without the user noticing). Right now the user won't notice but thats because on error it writes the Error to the error log. That doesn't work for me ... I like to try to do things the correct way lol
** EDIT **
Don't know if it will make a difference but I neglected to mention that the PROGRESSBAR and the LABEL are both in the status bar. They are not labels directly on the form.
|
|
|
|
|
Hi Jacob,
I think you handled the stopping and disposing the wrong way. For one, you should not implement a destructor; normally one implements a Dispose() method that disposes first by providing and calling a Dispose(bool) method, then calls SuppressFinalize. Your Dispose() not calling Dispose(bool) at all, I think your destructor is unreachable. On top of that I see no need for all of it.
This is what I would do:
D1. remove "IDisposable" and all dispose related code from LoadPicture. There is no need for LoadPicture to be disposable, it is not holding on to lots of memory that otherwise may get lost.
D2. implement a better Stop method; all you need is for LoadPicture to really have stopped somehow before you close the Form, and make the Progress/Finished events point to something that does no longer exist.
public void Stop() {
stop = true;
ProgressChanged = null;
Finished = null;
}
This is not waterproof yet, there is a slim chance of Load() to have tested say ProgressChanged (turned out to be not null), the main thread starting to close the form, setting ProgressChanged null, stop true, actually then closing the form, and only then Load calling ProgressChanged.
So you could:
- make stop volatile
- and test both the event and stop in that order (opposite from the Stop order), hence:
if (ProgressChanged != null && !stop) ProgressChanged(dataIndex, ...)
That should take care of it.
I do have more comments:
C1.
you used a strange way to cope with the end of the stream. I would simply use a loop containing
bytesRead += r.GetBytes(0, dataIndex, buffer, dataIndex, bufferSize);
dataIndex += bytesRead;
and exit the loop when bytesRead turns zero.
C2.
your progress reporting seems expensive, in two ways:
a. you switch from int/long to decimal, to cope with small sizes, which would vanish when divided by 1024 or 1024*1024.
b. and you report very frequently, so consecutive reports will not differ by much, probably wasting a lot of CPU cycles, and actually slowing down progress significantly.
I would use a larger data buffer (say 64KB), calculate an integer percentage locally, compare it to the previous value, and only report it on a change of percentage value.
C3.
You don't want your thread (t4) to ever prevent your app from exiting, so it is a background thread. You should tell it so: t4.IsBackground=true; before t4.Start();
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I am still trying your example.. Having issues with converting the bytesRead and chanigng the way I read the bytes.
Plus i think bytesRead would never be zero since you are using +=
|
|
|
|
|
Sorry, my mistake; you are right of course. What I meant was:
int newAmount = r.GetBytes(0, dataIndex, buffer, dataIndex, bufferSize);
bytesRead += newAmount;
dataIndex += newAmount;
and exit when newAmount is zero. You probably don't need both bytesRead and dataIndex now.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Here is my updated version. I set the thread to IsBackground = true and also on frmViewAsset closing it calls lp.Stop();
public void Load()
{
SqlConnection conn = new SqlConnection(AssetConfig.ConnectionString);
SqlCommand cmd = new SqlCommand("SELECT Picture FROM Inventory_Pictures WHERE PictureID=@Tag", conn);
cmd.Parameters.AddWithValue("@Tag", Tag);
try
{
conn.Open();
IDataReader r = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
if (r != null)
{
bool exist = r.Read();
if (exist)
{
long size = r.GetBytes(0, 0, null, 0, 0);
byte[] buffer = new byte[size];
int bufferSize = 65536;
long bytesRead = 0;
decimal prevPercent = 0;
while ((bytesRead < size) && ((size - bytesRead) > bufferSize))
{
if (stop)
break;
long newAmount = r.GetBytes(0, (Int32)bytesRead, buffer, (Int32)bytesRead, bufferSize);
bytesRead += newAmount;
if (newAmount == 0)
break;
decimal FileSize = (size / 1024) / 1024;
decimal CurrentSize = (bytesRead / 1024) / 1024;
if (ProgressChanged != null && !stop)
{
decimal currentPercent = (CurrentSize / FileSize) * 100;
if (currentPercent != prevPercent)
ProgressChanged((int)CurrentSize, (int)FileSize, Math.Round(CurrentSize, 2).ToString(), Math.Round(FileSize, 2).ToString());
prevPercent = currentPercent;
}
}
if (!stop)
{
MemoryStream ms = new MemoryStream(buffer);
if (Finished != null)
Finished(Image.FromStream(ms));
ms.Close();
}
}
r.Close();
}
}
catch (Exception ex)
{
Error.WriteError(ErrorType.SQL, "LoadPicture", ex.ToString());
}
finally
{
if (conn != null)
{
conn.Close();
conn.Dispose();
}
if (cmd != null)
cmd.Dispose();
}
}
Problem is ProgressChanged is apparently being called after frmViewAsset disposes??
[5/24/2010 10:39:13 AM LoadPicture]: System.InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at System.Windows.Forms.Control.Invoke(Delegate method)
at AssetMgmt.frmViewAsset.p_Finished(Image img) in C:\Applications\Windows Applications\AssetMgmt\AssetMgmt\frmViewAsset.cs:line 379
at AssetMgmt.LoadPicture.Load() in C:\Applications\Windows Applications\AssetMgmt\AssetMgmt\Operations\LoadPicture.cs:line 81
It fails on the Finished.. I think only because I can't close the window quick enough during the Progress. Funny thing is I saw the image appear in the picturebox before it finally closed and it still showed this
modified on Monday, May 24, 2010 11:39 AM
|
|
|
|
|
well, now it fails in finished, and rightly so; you basically have:
if (!stop) {
MemoryStream ms = new MemoryStream(buffer); <<< long operation
if (Finished != null) {
Image img=Image.FromStream(ms); <<< long operation
Finished(img);
...
}
and during those long operations another thread (the GUI thread handling your attempt to close down) has ample time to modify variables which you have already tested and passed.
Change it to:
if (!stop) {
MemoryStream ms = new MemoryStream(buffer); <<< long operation
if (Finished != null) {
Image img=Image.FromStream(ms); <<< long operation
if (Finished != null && !stop) Finished(img);
}
...
}
which you may simplify to:
MemoryStream ms = new MemoryStream(buffer); <<< long operation
Image img=Image.FromStream(ms); <<< long operation
if (Finished != null && !stop) Finished(img);
...
if you want (possibly causing some cycles being wasted in some scenario's)
BTW: the same applies to progress; there too, the inner conditional block should be minimal.
This approach isn't waterproof yet, it still is conceivable that the situation changes (variables change value AND form gets closed AND everything gets collected) between the if and the event being called. One extra safety measure would be to add a small delay in the FormClosing event:
change the variables
Thread.Sleep(100);
as the FormClosing will be followed by a FormClosed event, and only then the form will be disposed.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Ok maybe I am just being picky.
chnaged:
if (ProgressChanged != null && !stop)
{
decimal currentPercent = (CurrentSize / FileSize) * 100;
string CurrentMB = Math.Round(CurrentSize, 2).ToString();
string MaxMB = Math.Round(FileSize, 2).ToString();
int Current = (int)CurrentSize;
int Total = (int)FileSize;
if (currentPercent != prevPercent && ProgressChanged != null && !stop)
ProgressChanged(Current, Total, CurrentMB, MaxMB);
prevPercent = currentPercent;
}
if (!stop)
{
MemoryStream ms = new MemoryStream(buffer);
Image img = Image.FromStream(ms);
if (Finished != null && !stop)
Finished(img);
ms.Close();
}
This way like you were saying all the possible long process task are done before calling the event.
I put Thread.Sleep(100) in there and gave it a try. About 1/6 times I got the object disposed error. That only happened if I opened it and managed to IMMEDIATELY close it. (which i doubt users will be as quick as I was when working on this).
|
|
|
|
|
I agree with your code, and I'm surprised it still fails at that rate.
The reason for the sleep (and the imperfection of the approach) is, basically, you would need to use a lock; however I don't like putting a lock inside a FormClosing/FormClosed event, as any bug or behavioral problem in your app would cause it not to close at all, which tends to distress the user very much (no more than an exception that crashes the app though).
You might try one more refinement: inside FormClosing, rather than a single Thread.Sleep(100), do:
for(int i=0; i<5; i++) {
if (!t4.IsAlive) break;
Application.DoEvents();
Thread.Sleep(100);
}
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Lol I see where you say DoEvents is evil.. could you elaborate on that for me little bit so I know why?
As for the latest cost I think I might leave it as is. Because the user doesn't really notice the error message, it writes it behind the scenes to a file. Also it isn't happening that often now. Only when you close the form right when its opened.. Meaning you have to be trying to make it break for it to throw the error (which is what I'm doing lol)
I might leave it like it is.. I'm not fond of it not handling it like it should but what else do we do? I mean from what I know about programming it looks like technically it should work!!
The only thing I can think of is something with using the Invoke((Action) (()=> instead of the traditional Control.InvokeRequired. Don't know why but that is the only thing we haven't changed yet lol
|
|
|
|
|
1.
DoEvents() is evil because it adds re-entrancy to your code: pieces of code that were never going to be executed twice at the same time could suddenly run twice. Example:
public void Button_Click(...) {
long-wielding calculation
more long-wielding calculation
}
in the above, the GUI is dead as long as the calculations keep the GUI thread occupied. Inserting one or more DoEvent() calls, causes the message pump to get pumping again; now if you had clicked the same button, the same handler would suddenly run for a second time. And the handler's code was not designed in a thread-safe way as it was never expected to run concurrently. Each run would have its own set of local variables (as they are on stack, there is a stack for each thread), however the object's state, as maintained in the class data, could easily become inconsistent and invalid.
2.
I did not suggest modifying things that look fine; your Invoke (or one of its alternatives), while essential for things to go wrong, is not the cause of the problem.
3.
Jacob Dixon wrote: you have to be trying to make it break for it to throw the error (which is what I'm doing
Trying to break it is part of quality assurance; abuse is a must at that time!
If it were to fail when used normally, now that would really be unacceptable.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
hello everyone
I want to know how to specify the type of a variable declared as Object
better:
I have a variable type object, and I want to test whether this object is string it will make me so and so instrution and if this object and int, and so on.
thank you
Here is a snippet incomplet:
public static string Format(string format, object val,int length)
{
LineDefinition LD;
string var;
if (val.GetType() )
var = string.Format(LD.Format , val).PadRight (LD .Length ,' ');
var = string.Format(LD.Format, val).PadLeft (LD.Length, '0');
return var;
|
|
|
|
|
So you have a type that is an object and you want to determine whether or not it can be cast to a particular type. Is that what you are asking? If so (and if it is possible that the value comes in looking like a string), you can use the TryParse method on a particular type to determine whether or not it is of that type. You need to be careful with this approach because you need to carefully order the sequence of tests; this means that if you have the following:
object o = 10; then o could be a short, an int or a long.
If the variable looks like this example, then you can use the is operator to determine the type, e.g.
if (o is int)
{
}
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
in my case, I will use the second example,
thank you very much for your help, I really need it
|
|
|
|
|