|
The easiest and recommended way is to simply write everything to the file when saving. Technically, you could add and remove items from the file but this can be tricky.
Basically, you will read everything into the ListView. Allow the user to add or remove items as they see fit. Then to save, you simply write everything (which is everything in the ListView) to the file. Since you are overwriting the file, only items that are in the ListView will exist in the file after saving. This means items deleted by the user were removed and items added were inserted.
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
ok... i can go round it by have two listviews one fore save and next to show...
But heres a difficult question??
I have a button called split it means that i have listview1 that looks like this
for example:
(listview1)
columheader1, columheader2, columheader3, columheader4, columheader5
Online, k441211 DateTime.now , ad , whatever
if i click on this listview.item i want to copy the hole item with all the subitems in it EXCEPT subitem[1] it´s gonna look and check .txt file and count +1 if that is taken +1 if that is taken +1......
Little to hard to explain.. ;)
|
|
|
|
|
Sorry, I don't understand what you are trying to accomplish.
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
when i press a button on a selected listview.item its gonna copy that item and pass it to the same listview but it gonna controle subitem[4] in a .txt file that there are no one else with that name. If there is then add +1....
Know it´s hard, even to excplain!!
Gonna work the hole friday night, with this
|
|
|
|
|
lines[0] is the first line
lines[0][0] is the first char of the first line (but could throw an exception if
lines[0] is null or an empty string.
when checking for a single char, use '#' instead of "#"
string.StartsWith("#") seems appropriate here.
maybe you want to trim the line (with string.Trim()) before checking for #
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
What i´m trying to do is i have whrote a code and the user adds a path to a .txt file. And the user can add more paths so i thougt that: if line[21] have text go on with this code...
Tnx mates!!
-- modified at 17:37 Wednesday 5th September, 2007
|
|
|
|
|
Hello,
I understand that there's no such thing in C# as global variables, but I still need them Any known workaround or something else I'm missing here? thanx
|
|
|
|
|
You can define static classes and static fields like so:
public class GlobalVars {
public static Int32 MyInt = 0;
}
You can then access that field from anywhere like so:
GlobalVars.MyInt = 1;
Int32 i = GlobalVars.MyInt;
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
90% of the time, you don't need them at all. The other 10%, create a static class, and make the variables members of it.
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
This question has been asked, reasked, answered and reanswered exponentially I think.
No there are no global variables in C#.
If you want the closest match to a global variabel, you create a public static class and expose a public member variable for use as a 'globalish' variabel. Remember that you don't have to instanciate the class to access the variabel. Just use the class name directly.
I.e:
public static GlobalishVariabelHolder
{
private static int globalishIntegerVariabel = 0;
public static int GlobalishIntegerVariabel
{
get { return globalishIntegerVariabel;}
set { globalishIntegerVariabel = value;}
}
}
private void someMethod()
{
int value = GlobalishVariabelHolder.GlobalishIntegerVariabel;
}
-Larantz-
|
|
|
|
|
Bah, I should have thought of it myself Thanx
|
|
|
|
|
And in the world of OOP, if you're trying to use global variables extensively, this is usually a sign of a bad design.
|
|
|
|
|
Hi,
I'm trying to write a method that is passed an array and do some bit operations. I'm trying to figure out a way to determine the number of bits an element of the arrray. I could hardcode the value but I'd like the flexibility just changing the header and nothing else.
int count(Uint16[] data){
//Try to do something like
int bitsInCell = sizeof(data[0])*8;
//Instead of
int bitsInCell = 16;
}
I'm trying to do it the first way so if I want to sent Uint32, I don't have to search the code for 16 and switch them to 32.
Thanks for your comments.
|
|
|
|
|
You can use the Marshal class, which is defined in System.Runtime.InteropServices, like so:
int bitsInCell = Marshal.SizeOf(data[0]) * 8;
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
Warning: Marshal.Sizeof() and sizeof() do not always agree. Try bool !
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Good point. Technically, Boolean (bool) in C# maps to BOOL (int) in C++. Probably because bool is not used in the Win32 API.
Plus, I believe a C++ long in a 64-bit environment will be 64 bits, but the C# int (a.k.a. Int32) is 32-bits.
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
|
I'm using in a project an activeX component with these 3 methods:
<br />
public void PutData(ref int pData, int nBytes);<br />
public int GetDataSize();<br />
public void GetData(ref int pData);<br />
The same functions, in a c++ project are:
<br />
void PutData(long* pData, long nBytes);<br />
long GetDataSize();<br />
void GetData(long* pData);<br />
With the first function I pass a buffer to the component and the component copies it in its own buffer.
With the third function I pass a buffer to the component and the component copies in my buffer the data that it previously stored in its own buffer.
I can't get the component work properly, because it seems to copy only the first 4 bytes (= the first integer).
I tried the component in a c++ project and it works properly, so I think that the problem is in the way I'm passing the data to the activex.
I use the functions in this way:
<br />
int[] buffer = new int[10];<br />
int[] buffer_check = new int[10];<br />
<br />
for (int i=0; i<10; i++)<br />
buffer[i] = i;<br />
<br />
ocx.PutData(ref buffer[0], 10*sizeof(int));<br />
<br />
System.Diagnostics.Debug.Assert(ocx.GetDataSize() == 10*sizeof(int));<br />
<br />
ocx.GetData(ref buffer_check[0], 10*sizeof(int)); <br />
<br />
for (i=0; i<10; i++)<br />
System.Diagnostics.Debug.Assert(buffer_check[i] == buffer[i]);<br />
Someone has any idea about what I'm doing wrong?
Thanks!
Paolo
|
|
|
|
|
Hi Paolo,
The ActiveX is expecting a pointer to, presumably, an array of long values. But from C# you are only passing a single Int32. You need to use an IntPtr to pass the data back and forth, like so:
Int32[] buffer = new Int32[10];
buffer[5] = 1;
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)) * 10);
Marshal.Copy(buffer, 0, ptr, 10);
buffer[5] = 2;
Marshal.Copy(ptr, buffer, 0, 10);
Marshal.FreeHGlobal(ptr);
Note: The Marshal class is in the System.Runtime.InteropServices namespace.
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
It doesn't work
Your code works, but it stops if I use different unmanaged memory areas when storing and when retrieving or if I change the data in the unmanaged memory.
For example, this code doesn't work:
<br />
Int32[] buffer = new Int32[10];<br />
buffer[5] = 1;<br />
<br />
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)) * 10);<br />
Marshal.Copy(buffer, 0, ptr, 10);<br />
<br />
int bptr = (int)ptr;<br />
ocx.PutData(ref bptr, Marshal.SizeOf(typeof(Int32)) * 10);<br />
<br />
buffer[5] = 2;<br />
<br />
IntPtr ptr2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)) * 10);<br />
int bptr2 = (int)ptr2;<br />
<br />
ocx.GetData(ref bptr2);<br />
<br />
Marshal.Copy(ptr2, buffer, 0, 10);<br />
<br />
Marshal.FreeHGlobal(ptr);<br />
Marshal.FreeHGlobal(ptr2);<br />
|
|
|
|
|
Do you have access to the ActiveX source code? Or is it publicly available? If you have access, could you post examples of PutData and GetData. If it's publicly available, could you please provide a link.
If GetData is updating bptr2 so that it has the same value as bptr, then I would assume that PutData simply stored the long* that was passed in (instead of copying it). Then GetData is simply passing out the same long*. If this is the case then you do not need to allocate ptr2, because GetData does not required you to pass in a pre-allocated buffer.
This really depends on how the OCX methods are written and you would need a full understanding of how they work to properly use them. For example, if the PutData does in fact save the long* that was passed in, then the code below would cause access violations:
Int32[] buffer = new Int32[10];
buffer[5] = 1;
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)) * 10);
Marshal.Copy(buffer, 0, ptr, 10);
int bptr = (int)ptr;
ocx.PutData(ref bptr, Marshal.SizeOf(typeof(Int32)) * 10);
buffer[5] = 2;
Marshal.FreeHGlobal(ptr);
IntPtr ptr2 = IntPtr.Zero;
int bptr2 = (int)ptr2;
ocx.GetData(ref bptr2);
Marshal.Copy(ptr2, buffer, 0, 10);
In the code above, the long* that was cached is freed and then is accessed later. If you are only using the OCX in a serial fashion like your example, then it would be fine.
Let me know if this makes sense.
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
No, I haven't access to the activeX source code, but the activeX it is freely available at http://www.kolbasoft.com/
I put the test projects (c# and c++), the link to the activeX and a a few notes in www.vernazza.org/Vecad.zip
I agree with you, it seems that GetData is passing out the long* that I passed it before instead of the data pointed, but I can't understand why it works while I call that function from c++ , and it doesn't when I call it from c#!
|
|
|
|
|
You may want to use AllocCoTaskMem[^] instead (and it's associated free method), but I don't think that is your problem.
Looking at the put code:
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)) * 10);
Marshal.Copy(buffer, 0, ptr, 10);
int bptr = (int)ptr;
axVecad1.PutExData(ref bptr, 10 * 4);
After the first line, ptr points to the allocated block of memory. The array is then copied to the allocated block. Next ptr is cast to an int, so bptr now holds the correct address to the buffer. Now, when passing in the address to the PutExData, the address of the bptr is passed in (ref bptr). What you really want to pass in is the value of bptr. So really you are passing in a pointer to bptr which has a pointer to the actual data (so a pointer to a pointer).
Basically, the signature for the PutExData should have the first parameter as an "IntPtr", not as a "ref Int32". I don't think there is a way to properly pass in the IntPtr address when the signature has the ref value there. Because you would need to create an Int32 value at the same location as the allocated buffer.
I realize that VS generated the signature of the method for you (more specifically, aximp.exe generates it). The best work-around (short of hand-writing all the code you need) I found was here[^]. Be sure to read the whole thread, he talks about activeX controls later in the thread.
Hopefully this helps.
UPDATE: Actually, it looks like aximp.exe can generate C# source code now, so that would probably be your best option.
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
I would like to create a sidebar type application that sits on the right side of the client area. This application will always be executing, and I want it to always be visible.
Is there any way of controlling _other_ windows so that the won't maximise or be resized over/under that application? Optimally I would like another window to maximize to the full screen _except_ for the right X pixels where my sidebar application is residing.
Always on top will fix the "always visible" parameter, but using this other windows will be hidden behind it..
Preferrably I would like to set a registry value or such setting max size, but the next best case is to do this programmatically in my app.
Would really appreciate an answer!
Best regards
// T
|
|
|
|
|
|