|
Actually there is no such thing, you will have to maintain a variable yourself called previousIndex. Everytime the index changes set it. So in the next index change you can use it.
Hope this helps.
Live Life King Size
Alomgir Miah
|
|
|
|
|
But can I get a current index, inside SelectedIndexChanged event?
Thanks
|
|
|
|
|
Thats right.
this.tabControl1.SelectedIndex will give you the current index.
Live Life King Size
Alomgir Miah
|
|
|
|
|
There's no built-in way, something like a SelectedIndexChanging event. But it's easy to implement:
private int selectedTab = 0;
private int newTab = -1;
private void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e)
{
if(tabControl1.SelectedIndex == selectedTab ||
tabControl1.SelectedIndex == newTab)
return;
newTab = tabControl1.SelectedIndex;
tabControl1.SelectedIndex = selectedTab;
if(DialogResult.Yes == MessageBox.Show(this, "Sure?", "??",
MessageBoxButtons.YesNo))
{
tabControl1.SelectedIndex = newTab;
selectedTab = tabControl1.SelectedIndex;
}
newTab = -1;
} I hope this helps!
-- LuisR
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
Both of your replays are very informative, and helpful
Thank you very much.
|
|
|
|
|
You're welcome, I'm glad I could help!
-- LuisR
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
I already needed something similar, so I set up to implement it. Here's the result.
public delegate void TabControlCancelEventHandler(object sender,
TabControlCancelEventArgs e);
public class TabControlEx : TabControl
{
public event TabControlCancelEventHandler SelectedIndexChanging;
public TabControlEx()
{
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
if(newTab != -1)
return;
try
{
newTab = SelectedIndex;
SelectedIndex = selectedTab;
TabControlCancelEventArgs e2 = new TabControlCancelEventArgs(newTab);
OnSelectedIndexChanging(e2);
if(e2.Cancel)
return;
SelectedIndex = newTab;
selectedTab = SelectedIndex;
base.OnSelectedIndexChanged(e);
}
finally
{
newTab = -1;
}
}
protected virtual void OnSelectedIndexChanging(TabControlCancelEventArgs e)
{
if(SelectedIndexChanging != null)
SelectedIndexChanging(this, e);
}
private int selectedTab = 0;
private int newTab = -1;
}
public class TabControlCancelEventArgs : CancelEventArgs
{
public TabControlCancelEventArgs(int tab)
: base()
{
this.tab = tab;
}
public TabControlCancelEventArgs(int tab, bool cancel)
: base(cancel)
{
this.tab = tab;
}
public int Tab
{
get { return tab; }
}
private int tab;
} To use it, just subscribe to the SelectedIndexChanging event, and set e.Cancel to false if necessary.
Good luck!
-- LuisR
P.S. Sorry for the XML comments.
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
I am trying to use it, however even after declaring everything:
TabControl myTab = new TabControlEx ();
when I am trying to assign the event to myTab, I can't see Selected IndexChanging only the SelectedIndexChanged.
What am I doing wrong?
Thank you
|
|
|
|
|
Probably it's the Intellisense. Try writing:
myTab.SelectedIndexChanging += new TabControlCancelEventHandler(myTab_SelectedIndexChanging); [EDIT: is new TabControlCancelEventHandler and not TabControlCancelEventArgs ]
and then add the handler:
private void myTabSelectedIndexChanging(object sender, TabControlCancelEventArgs e)
{
if(validation fails)
e.Cancel = true;
} and compile the code. If you still can't post more details about the code, and I'll check it.
Good luck!
-- LuisR
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
Man, worked like a charm.
Once again thank you very much.
|
|
|
|
|
You're welcome.
I was thinking of writing a little article for this class, but I think it's a bit too simple.
Maybe I'll save it for a future "10 miscellaneous tips" article, or something like that. What do you think?
-- LuisR
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
Help articles are always welcome.
Especially if they are explained and outlined in the same manner
like you did to my TabControl poblem.
Thanks
|
|
|
|
|
I'll think about it and if I have some free time during the weekend, I'll write a small article.
-- LuisR
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
In the topic
Cursor Constructor (Type, String) it tells how to add a cursor as a resource to your project so you can open it at runtime without copying around a second file.
There are two parts of it I do not understand. One is that it only talks about the command line changes. What command line? I build from the IDE. The other is the GetType call. What am I supposed to get the type of?
The sample from the help system:
Using the C# compiler:<br />
csc /resource:"MyWaitCursor.cur","MyCursors.MyWaitCursor.cur" MyCursor.cs<br />
Using the Visual Basic compiler:<br />
vbc /resource:"MyWaitCursor.cur","MyCursors.MyWaitCursor.cur" MyCursor.vb
(This sample is in VB rather than C#. Blame MS.
' Looks namespace.MyCursor.cur in the assemblies manifest.<br />
<br />
' The following generates a cursor from an embedded resource.<br />
' To add a custom cursor, create or use an existing 16x16 bitmap<br />
' 1. Add a new cursor file to your project: <br />
' File->Add New Item->Local Project Items->Cursor File<br />
' 2. Select 16x16 image type:<br />
' Image->Current Icon Image Types->16x16<br />
' --- To make the custom cursor an embedded resource ---<br />
' In Visual Studio:<br />
' 1. Select the cursor file in the Solution Explorer<br />
' 2. Choose View->Properties.<br />
' 3. In the properties window switch "Build Action" to "Embedded"<br />
' On the command line:<br />
' Add the following flag:<br />
' /res:CursorFileName.Cur,Namespace.CursorFileName.Cur<br />
'<br />
' The following line uses the namespace from the passed-in type<br />
' and looks for CustomCursor.MyCursor.Cur in the assemblies manifest.<br />
' NOTE: The cursor name is acase sensitive. <br />
<br />
Me.Cursor = New Cursor(Me.GetType(), "MyCursor.Cur")
--------------
Will Pittenger
|
|
|
|
|
1: You only have to read the command line part if you're using the command line to build your projects (and you don't). People that don't have Visual Studio, but only the .Net Framework, can still build projects with the command line, or something like that.
2: You have to give a type, because the cursor looks in the assembly(project) of that type for the resource you specified in the second argument. If you do Me.Cursor = New Cursor(GetType(System.Windows.Forms.Form), "MyCursor.Cur") , you ain't gonna get a cursor, because the System.Windows.Forms.dll doesn't have a 'MyCursor.cur' resource.
Hope this helps!
Will L Pittenger wrote:
This sample is in VB rather than C#. Blame MS.
You gotta love those Redmond guys for that!
|
|
|
|
|
1. GetType is still not a valid function. What namespace is that in?
2. Since I do not want a cursor from the Forms dll but rather my executable, what do I pass GetType?
--------------
Will Pittenger
|
|
|
|
|
1: Dunno, it's a VB.Net operator, i doubt if those are in namespaces. You can use this.GetType() .
2: Well, just pass this.GetType() , and the constructor will look for the cursor in your executable, and in the namespace of this (i think i forgot to mention that) If you want to get a resource in code, you have to get. Example:
namespace BlaBla {
class MyForm : System.Windows.Forms.Form {
cursor GetCursor {
IO.Stream stream = Reflection.Assembly.GetCurrentAssembly.
GetManifestResourceStream("BlaBla.Cursor.ico")
cur = new Cursor(stream);
stream.Close();
Cursor cur = new cursor(this.GetType(), "Cursor.ico");
return cur;
}
}
}
Oh yeah, and if you want a colored cursor, you can do this:
Instead of adding a .cur resource to your project, add a colored .ico Icon resource.
Then you can do Cursor cur = new cursor(this.GetType(), "Cursor.ico");
Hope this helps!
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.."
-- Mark McCormick
|
|
|
|
|
No good. Since I only needed one instance of the cursor, I made it static. I wanted to prevent changes, so I added readonly.
I took the readonly part out so I could see if the rest was right.
With the following code to allocate a cursor:
if(cursorMovingCol == null)<br />
cursorMovingCol = new System.Windows.Forms.Cursor(GetType(), "DataListTest.movingCol.cur");
I get the following:
An unhandled exception of type 'System.ArgumentNullException' occurred in system.windows.forms.dll<br />
<br />
Additional information: Value cannot be null.
--------------
Will Pittenger
|
|
|
|
|
Ooh, it's static? Didn't know that!
Then this.GetType doesn't work...
static Cursor Getcursor{<br />
System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream("movingCol.cur");<br />
System.Windows.Forms.Cursor cur = new Cursor(stream);<br />
stream.Close();<br />
return cur;<br />
}
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.."
-- Mark McCormick
|
|
|
|
|
First, you appear to be mixing languages. I assume you meant to have me declare GetCursor as a function. You made it a property. You needed a () after the function name.
Second, it appears that GetExecutingAssembly is a function, not a class or namesspace. So again, I added a () after the function name.
Neverless, I still get an exception. Same as before.
Resultant Code (Same error):
private static System.Windows.Forms.Cursor GetCursor()<br />
{<br />
System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly()<br />
.GetManifestResourceStream("movingCol.cur");<br />
System.Windows.Forms.Cursor cur = new System.Windows.Forms.Cursor(stream);<br />
stream.Close();<br />
return cur;<br />
}
--------------
Will Pittenger
|
|
|
|
|
Yeah, i don't know C#, i'm from VB.Net...
Thank God that it's all .Net!
Why don't you try this, it will print all the resources in your app:
String() res = Reflection.Assembly.GetExecutingAssembly.GetManifestResourceNames();
int i;
for (i=0; i<res.Length; i++){
Console.WriteLine(res(i))
}
If movingCol.cur is somewhere in that list, you have to use the entire name in GetCursor (maybe that includes a namespace or something). If you can't find movingCol.cur anywhere in the list, make sure it's an embedded resource (in Solution Explorer: right-click movingCol.cur, Properties, Build Action = Embedded Resource.
Cheers!
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.."
-- Mark McCormick
|
|
|
|
|
Please do me a favor and pick a language.
Since this does not appear to be what I know of C#, I am noting some comments. Feel free to skip them if you will always use VB in samples. (However, if you continue to assist C# users besides myself, you might want to learn more C#. You would help them out. Many would not know VB. I know a little and can do some translation.)
1. Specifying "String()" is invalid. You are attempting to declare a function named String with an unknown return type and no parameters. Since you mentioned System.Reflection.Assembly.GetEntryAssembly() (minus the System part), I looked up that function and found it returned an array of strings. The C# syntax for that is "string[]".
2. You did not complete the for's condition or increment clauses. You also could have declared "i" inside the for. Hence, that could have looked like "for(int i = 0; i < res.Count; i++)". However, I decided I could skip storing the array and declaring the int by using a foreach statement. See below.
3. Again, you array syntax is VB. "res(i)" should read "res[i]". Remember, C# is highly related to C/C++.
This is the code I came up with:
foreach(string strManifestResourceName in System.Reflection.Assembly.GetEntryAssembly()<br />
.GetManifestResourceNames())<br />
System.Diagnostics.Trace.WriteLine("Found Resource: " + strManifestResourceName);<br />
<br />
System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly()<br />
.GetManifestResourceStream("movingCol.cur");<br />
System.Windows.Forms.Cursor cur = new System.Windows.Forms.Cursor(stream);<br />
stream.Close();<br />
return cur;
That results in this output:
Found Resource: DataListTest.res.movingCol.cur<br />
Found Resource: DataListTest.Form1.resources<br />
Found Resource: DataListTest.dataListHeaderCtrl.resources<br />
Found Resource: DataListTest.dataListCtrl.resources<br />
Found Resource: DataListTest.dataListHeaderCtrlNoChild.resources
I then changed the original code that specified the resource to replace "movingCol.cur" with "DataListTest.res.movingCol.cur". It now loads properly. I have also added code to verify that the cursor is what I want. I may make changes later. I am just getting around to actually needing it. (I was there when I created the cursor, but then I decided to rearrange. Delays. )
Thank you for your help. Sorry if I seemed critical about your C# knowledge, but many C# users may not know VB. They might recognize the function calls, but something like "String()" will confuse C# developers that do not have at least some VB experience. Even then, it took a while for me to figure out what you wanted. I almost asked you to just give me the VB version. Then I noticed parts were VB.
--------------
Will Pittenger
|
|
|
|
|
Well i'm glad it works now!
About the C#:
That is definetly a problem. I know how to read it, but i'm a bitch at writing it... All those { and }, it's driving me mad! I know it looks a lot like C++, but i know even less about that . Anyway, before i post something in this forum again, i'll be sure to rag it through Reflector or something. That always works for me!
Mzl..Marc
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.."
-- Mark McCormick
|
|
|
|
|
Can someone give me a suggestion? I've tried several different methods of creating this form and destroying it when I am done, all with the same results. This seems to be the cleanest and easiest method to use but it still does not give a good result.
using (frmContainer FrmMP = new frmContainer(null, TFormList.MasterParts, -1))<br />
{<br />
FrmMP.SetSalesOrderInfo(SelectedOrderNumber, SelectedReferenceNumber);<br />
FrmMP.ShowInTaskbar = false;<br />
FrmMP.StartPosition = FormStartPosition.CenterParent;<br />
FrmMP.ShowDialog();<br />
}<br />
Upon opening this window, I've added 3K to my memory. Wouldn't be a problem except it gets called several times per hour. For some people this is 100K per hour. The only way I've been able to actually get the memory collected is by minimizing and then resuming the program. Not very convenient for the user and they don't know when they need to go through that ritual (nor should they).
I've tried several different calls to do garbage collection (even though it is not recommended) but these didn't work either. A session will usually start at about 10K. When it hits a couple hundred K, I can minimize and restore the pgm and it is usually back down to 15-20K. If I do not minimize, it just continues to grow.
Any suggestions?
|
|
|
|
|
I have seen this behavior with just about any Windows program. VS6 was pretty bad, Word, Lotus Notes, and many others. You could try to set your FrmMP = null; I have seen others do that where they were trying to reclaim memory.
Steve Maier, MCSD MCAD
|
|
|
|