|
How do I disable the selection of a particular node in a tree..
Eg. I don't want to add children to nodes already children.. I can show a messege box.. or do a no-op if a child is selected, but can I disable its selection?
_____________________________________________________
Believe! Every thing has a purpose
|
|
|
|
|
You can cancel the selection of a node by handling the TreeView.BeforeSelect event:
treeView1.BeforeSelect +=
new TreeViewCancelEventHandler(treeView1_BeforeSelect);
private void treeView1_BeforeSelect(object sender,
TreeViewCancelEventArgs e)
{
if (e.Node.Nodes.Count > 0) e.Cancel = true;
} If you want to have more control over what people can add, this is where encapsulation comes in. Rather than trying to hack the TreeView to allow/disallow certain operations, host the TreeView in a UserControl or something where you define methods and properties that reflect operations in the TreeView . This way you can easily perform a check before doing something, like how many nodes exist and whether you should add a new one. To implement this kind of behavior on the tree can be quite difficult. This is the reason for encapsulation.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
ok..
I'll try this.. thank you.
_____________________________________________________
Believe! Every thing has a purpose
|
|
|
|
|
Hello,
I'm having a problem to read data from my bluetooth gps mouse!
In detail: I'm trying to program a little tool for an IPaq 5450 PPC 2003 which reads the gps data that comes in from the virtual com port (in my case com port 8). That is where my problem begins. I'm pretty new with c# and serial port communication at all! So i hope anyone of you can help me with that problem! How do i open the serial com port in c# and start reading out of a buffer!
I just need the simple geographical coordinates. Not more!
And please no recommendation to use another language... i have to use c#, because it's part of a bigger project!
hope someone can help me...
nils
|
|
|
|
|
.NET 1.x does not include a serial stream reader/writer class; .NET 2.0 will (finally). There are several classes available that people have written to get around this problem. If you try the following search, you'll find several hits:
http://www.codeproject.com/info/search.asp?cats=3&cats=5&searchkw=serial+com+port[^]
As far as using another language (because you're easiest way to talk to a serial port is using Managed C++), you do realize that you can write assemblies using any managed language, don't you? You could, for example, write an assembly in Managed C++ (typical when many native functions and supporting data types need to be used) and reference that in your C# project just like you reference System.dll, System.Data.dll, etc. The .NET BCL assemblies are written in C# yet they're used by all other managed languages (MC++, VB.NET, Perl.NET, COBOL.NET, etc.).
Use what makes it the easiest.
If you want additional help for reading NMEA data from your GPS unit, try the following google search:
http://www.google.com/search?q=GPS+C%23[^]
There are many great examples and even some third-party libraries which could do all this for you.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Have a look at GPS Reader NMEA 0-183[^]
He uses a DBComm dll.
Also nice way of showing sat's on screen.
Good starting point,...
|
|
|
|
|
well, looks like what i'm looking for! but do i need to write the dbcomm.dll on my own or can i download it somewhere. so far i wasn't able to find it!
nils
|
|
|
|
|
|
I'm using this code (from a MS example) to encrypt/decrypt simple strings. These methods work fine while I maintain an instance of the class but if I encrypt a string, then later want to decrypt it (using the same key of course)
the first 5 characters or so are messed up.
<br />
public string EncryptString(string strValue)<br />
{<br />
SymmetricAlgorithm m_csp = new TripleDESCryptoServiceProvider();<br />
ICryptoTransform ct = m_csp.CreateEncryptor(m_csp.Key, m_csp.IV);<br />
byte[] byteBuf = Encoding.UTF8.GetBytes(strValue.PadLeft(5, '*'));<br />
MemoryStream ms = new MemoryStream();<br />
CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);<br />
cs.Write(byteBuf, 0, byteBuf.Length);<br />
cs.FlushFinalBlock();<br />
cs.Close();<br />
<br />
return Convert.ToBase64String(ms.ToArray());<br />
}<br />
<br />
public string DecryptString(string strValue)<br />
{<br />
SymmetricAlgorithm m_csp = new TripleDESCryptoServiceProvider();<br />
ICryptoTransform ct = m_csp.CreateDecryptor(m_csp.Key, m_csp.IV);<br />
byte[] byteBuf = Convert.FromBase64String(strValue.Trim());<br />
MemoryStream ms = new MemoryStream();<br />
CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);<br />
cs.Write(byteBuf, 0, byteBuf.Length);<br />
cs.FlushFinalBlock();<br />
cs.Close();<br />
<br />
return Encoding.UTF8.GetString(ms.ToArray());<br />
}<br />
<br />
|
|
|
|
|
Something obviously is stored in that class that you're not saving (perhaps the key, which in these snippets is getting created each time, even between encryption and decryption calls).
How are you saving the ciphertext across calls and instances of the containing class? Are you writing them to a file? If you use a TextWriter , you may be inadvertently writing a BOM (byte order mark) to the beginning of the file. Depending on how you read the file back in, this BOM may become part of the ciphertext (a TextReader should strip this, but if you use a FileStream or something, it won't be stripped from the rest of the ciphertext, for example).
The only thing with block ciphers is, though, that if something is screwed up then the ciphertext would be invalid. The only possibility for this not to happen as I see it is if a particular block of ciphertext were changed and the block data size wasn't changed, and this may only work (depending on the algorithm) if the data wasn't signed, either (because the digest would be invalid). If this is possible (depending on the algorithm), then the rest of the blocks should decrypt.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks Heath, I found the error. The key being used was the same for encryption and decryption but I was generating the initalization vector each time ( GenerateIV() ). After I made sure to use the same for each way it works fine. Doh!!
|
|
|
|
|
1.Is there anyway, when selecting a chart in a report, to have it enlarged on the next page automatically such as 150% bigger?
2. The Y axis of the graph gets cut off if it has a too large number.(start from Zero). How to enlarge the margin to show the whole number? And how can I put a number starts from ( if not from Zero) and how can I define an increment step by my own?
3.To show a summary of a report field in a chart, it will show 'Sum of TableName.FieldName' Format in the legent. I want to customize a name for the summary such as 'Total Sales' instead of ' Sum of SalesTable.SalesPerMonth ',
I have tried to define a custom field to hold the summary resault, but the chart is showing @TotalSale. with '@' in legent.
How can I customize a name for the legend?
Thanks in advance.
|
|
|
|
|
so i finally came across a situation today that i thought would be ideal if i were able to implement an anonymous class on the fly like you can in java. by default, ComboBoxes use the ToString() method as the listed label when you add an item to it. So if you create a new object, add it to the comboBox, it will be listed as a "System.Object". What I wanted to do was to simply add an object for only one purpose, to list itself as "ALL". So I created a class just so I can override the ToString() to return "ALL" and passed it into the Items.Add(). it would have been nice to do it like in java like so:
ComboBox.Items.Add(new object(){
public override string ToString(){
return "ALL";
}
})
but u can't do that in C#.
any comments?
|
|
|
|
|
Unless I'm misunderstanding, C# provides a much more elegant way to do this:
ComboBox.Items.Add("ALL");
#include "witty_sig.h"
|
|
|
|
|
haha, OK, i agree, your way is a tad more elegant.
but ok, for the sake of argument, what IF there were no overloaded version that took a string argument, and internally the ony way to make the display change was to alter the ToString() method. and maybe you want to add a few things to the class and don't need to save references to the objects. THEN wouldn't it be nice to have anonymouse classes?
|
|
|
|
|
Actually it's not an overloaded method. All types in the .NET BCL (pointers aside) inherit from System.Object. Since a the listbox wants an object, you can pass literally anything into it, an int, string, bool, whatever.
Now as for anonymous classes, the case you're making for is anonymous objects. To me I don't see a real need; you're defining and instanciating an object in place -- if you really need to instanciate with custom data just use a regular class; less clutter and more concise code that way IMO. But maybe that's just me.
#include "witty_sig.h"
|
|
|
|
|
And why would you want to? As Judah humorously pointed out, there's a much more elegant way of doing it.
C# 2.0 will, however, allow something similar in fashion for delegates. So instead of having to define a method in order to use a delegate (event handler, callback, etc.), you can define it inline, similar to anonymous definitions like you find in Java.
There's things that C# and .NET in general have that Java can't do similarily as well. To each his own.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I want to compare two byte buffer quickly. I used to do this with memcmp in C. I can't find a function to do that in C#.
I'm sure there is one, but I can't find it.
BRCKCC
|
|
|
|
|
There really isn't a way as fast as memcmp , so if you need that kind of performance, you can always P/Invoke it:
using System;
using System.Runtime.InteropServices;
class Test
{
static void Main()
{
byte[] b1 = new byte[10];
byte[] b2 = new byte[10];
for (int i=0; i<b1.Length; i++)
b1[i] = b2[i] = Convert.ToByte(i);
Console.WriteLine("Equals: " + b1.Equals(b2));
Console.WriteLine("Object.Equals: " + Object.Equals(b1, b2));
Console.WriteLine("memcmp: " + Compare(b1, b2));
}
static bool Compare(byte[] b1, byte[] b2)
{
IntPtr retval = memcmp(b1, b2, new IntPtr(b1.Length));
return retval == IntPtr.Zero;
}
[DllImport("msvcrt.dll")]
static extern IntPtr memcmp(byte[] b1, byte[] b2, IntPtr count);
} This would print:
Equals: False
Object.Equals: False
memcmp: True By doing this you sacrific portability, however. If you don't need that kind of performance, use a simple for (not foreach , which is slower) loop and compare each byte using the == equivalency operator.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I'm using the for loop and since I don't want to sacrifice portability, I'll stick with the for loop.
Thanks.
- Bruce
BRCKCC
|
|
|
|
|
Also, if you'd be allowed to use unsafe code, it would be much faster. You'd be able to loop thru the array cast to array of ints and comparing 4 bytes at a time. Plus the CPU works better with int values than single byte values. Of course you'd have to have a special case for padding bytes.
|
|
|
|
|
Do you have a snippet of code on how to do this "casting"?
BRCKCC
|
|
|
|
|
Here is a simple program that tests the comparison using safe and unsafe version. On my machine the unsafe version is about 4 times as fast as safe version.
You have to make sure you allow unsafe code in project properties.
Note, this will only work with arrays whose size is divisble by 4. You can easily change it to handle the last 1, 2 or 3 bytes specially, but i'll leave it as excercise.
using System;
namespace Tester
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
const int repeats = 200;
byte[] bytes1 = randomBytes(4 * 1000000);
byte[] bytes2 = new byte[bytes1.Length];
for (int i=0; i<bytes1.Length; i++)
bytes1[i] = bytes2[i];
int start_t = System.Environment.TickCount;
for (int r=1; r<=repeats; r++)
{
bool res = CompareUnsafe(bytes1, bytes2);
if (r == repeats)
Console.WriteLine("Result: " + res);
}
int end_t = System.Environment.TickCount;
Console.WriteLine("CompareUnsafe: {0} ms.", (end_t-start_t));
start_t = System.Environment.TickCount;
for (int r=1; r<=repeats; r++)
{
bool res = CompareSafe(bytes1, bytes2);
if (r == repeats)
Console.WriteLine("Result: " + res);
}
end_t = System.Environment.TickCount;
Console.WriteLine("CompareSafe: {0} ms.", (end_t-start_t));
}
public static bool CompareSafe(byte[] byteArray1, byte[] byteArray2)
{
if (byteArray1.Length != byteArray2.Length)
return false;
for (int i=0; i<byteArray1.Length; i++)
if (byteArray1[i] != byteArray2[i])
return false;
return true;
}
public unsafe static bool CompareUnsafe(byte[] byteArray1, byte[] byteArray2)
{
if (byteArray1.Length != byteArray2.Length)
return false;
if (byteArray1.Length % 4 != 0)
throw new ArgumentException("Byte arrays have to be divisible by 4", "bytearray");
fixed (byte* bytes1 = &(byteArray1[0]))
fixed (byte* bytes2 = &(byteArray2[0]))
{
int* ints1 = (int*)bytes1;
int* ints2 = (int*)bytes2;
int size = byteArray1.Length / 4;
for (int i=0; i<size; i++)
if (ints1[i] != ints2[i])
return false;
}
return true;
}
public static byte[] randomBytes(int size)
{
Random r = new Random();
byte[] bytes = new byte[size];
r.NextBytes(bytes);
return bytes;
}
}
}
|
|
|
|
|
Thanks very much.
- Bruce
BRCKCC
|
|
|
|
|
Hi All,
I'm calling an unmanaged function (SetScrollPos()) from my C# code and when I try to instantiate the class that uses this method I get a TypeLoadException with the following message:
Additional information: Could not load type Tradition.TraditionDesktop.TraditionDesktopClient.PageMonitor from assembly PageMonitor, Version=1.0.1641.23960, Culture=neutral, PublicKeyToken=null because the method SetScrollPos has no RVA.
What exactly is an RVA ?
|
|
|
|
|