|
Hi,
I am using sorting feature in multiple columns in a gridview. My gridview sorting is like this:
protected void gView_Sorting(object sender, GridViewSortEventArgs e)
{
try
{
if (this.ParentPortlet.PortletViewState["direction"].ToString() == "")
{
this.ParentPortlet.PortletViewState["direction"] = " ASC";
}
else if (this.ParentPortlet.PortletViewState["direction"].ToString() == " ASC")
{
this.ParentPortlet.PortletViewState["direction"] = " DESC";
}
else if (this.ParentPortlet.PortletViewState["direction"].ToString() == " DESC")
{
this.ParentPortlet.PortletViewState["direction"] = " ASC";
}
}
catch
{
this.ParentPortlet.PortletViewState["direction"] = " DESC";
}
getData(e.SortExpression.ToString(), this.ParentPortlet.PortletViewState["direction"].ToString());
}
I have four columns in the gridview (Name, Date, Location, Cell) and all these columns are sortable. so If i click name, it sorts in desc order and again if i click it, it will sort in asc order which is great. Similar with the other fields. But my problem is If I click the Name, it will sort in desc order. Now If i click Date, it will sort in asc order. Again If I click the Name, it will sort in desc order. Is there any way we can put these sortings independent to each column. Like, If I click Name, it should sort in desc order. Now If I click date, it should sort in desc order. Now again, If i click Name, it should sort in asc order.
Any ideas?
suchita
|
|
|
|
|
Using a Hashtable, or similar structure, to store the sort direction based on column is about the only way to get this done I can think of at the moment
No comment
modified 25-Oct-11 14:45pm.
|
|
|
|
|
Can you point me to any example on this, please?
suchita
|
|
|
|
|
|
Hi,
I don't know about GridView. However I can tell you about WinForms' DataGridView:
1.
if you provide no code at all, it will sort itself as it should; each column remembers its sort direction, and will toggle it every time you hit the column header without having hit another column header.
2.
It does not have a Sorting event (i.e. no pre-Sort), it does have a Sorted event (post-Sort).
BTW: GridViewSortingEventArgs.SortDirection tells you how the GridView is going to be sorted. Either it is column-specific or unique for the entire GridView, I don't know (and MSDN seems not to be clear on this). If it is column-specific, you should just use it; if it is a single bool covering all columns, you need to replace it by one bool per column, a HashTable could help you do that.
|
|
|
|
|
I have no idea how do we use hashtable for each column event for gridview..
suchita
|
|
|
|
|
you want to hold one boolean flag for every column, but have them structured, not just a bunch of loose flags. There are several ways to do that.
One way is by holding an array of four bools, one for each column, and use the column number as the array index.
A more elastic approach would rely on a HashTable or better yet a Dictionary<string,bool> where the key could be the column header text (they have to be unique!), and the value is the bool itself. That way you can find the bool for a column by feeding the column header text to the HashTable/Dictionary.
BTW: you could use the Column itself as the key, however that may or may not be any easier.
PS: if you're new to HashTable/Dictionary you should read up on those classes.
|
|
|
|
|
Hi all,
I want to create a setup of my c# application with some merge modules adding in to it and without using visual studio deployment kit.
Is there any other third party software which can do it.For example like InstallShield.
Thanks in advance.
|
|
|
|
|
InstallShield. Wix. InnoSetup. They all can manage this - it's a fairly fundamental requirement of installer applications.
|
|
|
|
|
I written this test code that places a form onto tab pages. Each button click creates a new tabbed page with two colored forms on it. I've gotten some suprise that this is in fact possible. Nevertheless, I need to find a way to have each form run in its own thread. Does anybody have any ideas how this might be done?
Form1 has a button and a tabControl
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
Form3 form3 = new Form3();
tabControl1.TabPages.Add("tabPage" + (tabControl1.TabPages.Count - 1).ToString());
form2.TopLevel = false;
form2.BackColor = Color.Blue;
tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(form2);
form3.TopLevel = false;
form3.BackColor = Color.Red;
tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(form3);
form2.Show();
form3.Show();
}
|
|
|
|
|
Why do you think you need that?
In WinForms all GUI elements (Controls) should be created by the main thread, and that thread only then is allowed to touch them, so what you are after is nearly impossible. In a normal application, all event handlers are swift, so there should be no reason to reorganize things in a way Windows doesn't like. If one of the handlers (say a Button_Click handler) needs to execute long winding code, then that code itself should be executed by another thread (and not touch any Controls); a BackGroundWorker often comes in handy here.
You may want to read this article of mine[^].
BTW: I don't know why you want to add a Form to a TabPage, adding a UserControl is easier and often is all one needs; and using DockStyle.Fill is often what I want.
|
|
|
|
|
You might say for the challenge of it, doing what seems impossible can be fun, but really because I need this level of functionality. I have actually accomplished the task. Here's how I did it.
Main Form - Click Button to add a new Form2 to a tab control
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
tabControl1.TabPages.Add("tabPage" + (tabControl1.TabPages.Count - 1).ToString());
form2.TopLevel = false;
form2.BackColor = Color.Blue;
tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(form2);
form2.Show();
}
Form2 - Has a top panel strip with a button, that when pressed opens a child form (Form3) in its own thread, within the area of second panel that sits below the top panel.
public partial class Form2 : Form
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
public Form2()
{
InitializeComponent();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
ThreadStart ts = new ThreadStart(StartUiThread);
Thread t = new Thread(ts);
t.Start();
}
public void StartUiThread()
{
var frm3 = new Form3();
IntPtr intptr = new IntPtr();
this.UIThread(delegate { intptr = this.panel2.Handle; });
SetParent(frm3.Handle, intptr);
Application.Run(frm3);
}
}
public partial class Form3 : Torbo.DockableForm
{
public Form3()
{
InitializeComponent();
}
private void Form3_Load(object sender, EventArgs e)
{
label1.Text = "Thread: " + Thread.CurrentThread.ManagedThreadId.ToString();
}
}
static public void UIThread(this ATE_nonATE control, Action code)
{
if (control.InvokeRequired)
{
control.BeginInvoke(code);
return;
}
code.Invoke();
}
Two myths are busted here. You can put forms onto other controls like a tabControl and it is possible to create threaded child forms.
|
|
|
|
|
You can, but the question still remains why you should. Anything that's going on in a background thread must (by definition, since you can't update the UI directly from it) be business logic and therefore shouldn't be in the same class as the 'view' (in view/model terms), i,e, the form. Running two message loops will cause surprising things to happen, e.g. message boxes spawned on one thread aren't in the same modal UI stack as forms in another, so they don't stop operation. I think the same applies to other modal dialogs (i.e. called with ShowDialog), and the Z-order rules (topmost forms etc).
|
|
|
|
|
There has never been a 'myth' that you could not put a WinForm inside other Container objects' Controls Collection ... as long as you set the TopLevel property to 'false.
Yes, you are 'free' to create things as weird as a Form inside a TextBox:
Form2 f2 = new Form2();
f2.TopLevel = false;
textBox1.Controls.Add(f2);
f2.Show();
And, ready the bell, book, and candle, you can even do this:
Form2 f2 = new Form2();
f2.TopLevel = false;
f2.Parent = textBox1;
f2.Show();
But the interesting question is: why you would want to use a Form inside another container in the first place.
I stand ready for you to illuminate me on that, and I'd be happy to learn my assumptions are incorrect !
A WinForm is not a "light-weight object." And UserControls and Panels ... and later .NET additions like FlowLayoutPanel and TableLayoutPanel ... at least Panel and UserControl being much lighter-weight than a Form ? ... are really the "designated hitters" for use as containers of Controls within Forms, or other container controls.
A UserControl, or a Panel, can actually have size co-ordinates larger than the effective screen resolution: a Form cannot. Forms come with a baggage of adorner buttons (Max, Min, ControlBox), and various properties and methods, you will probably not need when one is used inside another Control.
In case someone trots out old the old war-horse, MDI architecture on this thread as a case for Forms inside a Form: rest-in-peace, MDI. Your gargoylish time came and went, and, for your time, you were, perhaps like Quasimodo in "The Hunchback of Notre Dame," necessary to ring some bells, but, sorry, we got new-fangled carillons these days that look a lot smarter.
We got 'TopMost' to make floating windows now, say halleleujah !
I don't pretend to understand what you are doing with threading in your code, but it looks like an interesting experiment. My one question would be that if you are using the standard Program.cs method of launching the app by creating an instance of a primary Form: when the user closes that primary Form, which normally auto-shuts-down all other created Forms ... and you've got this child-form which you voodoo'd to make run in a separate thread: what happens to that own-thread child-form ? Does the thread terminate properly ? Is the child-form window closed as usual ?
I hope I don't sound critical here: I have a history of learning/exploring technology by 'tormenting' structure, and 'pushing the envelope' to see what happens, myself
One of my favorite experiments, years ago, was a collection of sticky-notes (individual Forms) that ... in reponse to a certain key-stroke combination on any of the sticky-forms ... 'collapsed' into a single Form with a TabControl, where all the Controls in each sticky-Form appeared in separate TabPages, each titled with the name of the sticky-Form. But ... I remained pure ... and the TabPages were not violated by Forms
And then, you typed the same keystroke combination on this Main Form and it was made invisible, and all the sticky-Forms were 'exploded,' shown again, restored to their last location: fun !
By the way, there are some interesting things done with multiple AppDomains in a WinForm project in Chris Sells' book on WinForms from Addison-Wesley, on which I was a technical-editorial consultant ... I think they might interest you.
best, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
Bill, part of why I'm doing this is to see if it was possible. Second, I really could not find anything much about placing forms on controls on the Net. I was aware of TopMost = False to make it work, but folks seem to say that the form needed to be placed on a panel within the tabControl, which clearly it does not. Now the problem with setting topMost = false is that the form on the tabControl can not be used as a MDI container to create child forms, since as far as I know, topMost must be set to true.
Hence, the second piece of what I did was to create these childforms. Interestingly, it was possible for each childform to run in its own thread if you want it to. As far as I know, the behavior of the forms are as you would expect on closing. The big draw back it that there is a offset created between the cursor position and the corner of top left corner of each childform. This I'm hoping can be coded out. Unless you know of a way to fix the problem. I'd be happy to post a rar file of my test application if it were possible were possible in this forum. I think it's an interesting app to play and explore with.
OK, why am I doing this. Well, and maybe I'm climbing the wrong tree here, but I need to place an ActiveX control on each childform. I want each ActiveX control to run in there own thread. My understanding is that normally the ActiveX control can only run in the main GUI thread, and that's not what I want. Hopefully, this makes sense. Perhaps there is a better way, but I'm only a novice coder.
modified 25-Oct-11 9:59am.
|
|
|
|
|
boreland wrote: folks seem to say that the form needed to be placed on a panel within the
tabControl
I'm not sure where you'd have heard that. A tab page is a panel in its own right.
|
|
|
|
|
Hi, I hope my responses are received by you as in the spirit of appreciation for your curiosity and experimental attitude !
I think (if I understand what you are pursuing here) the broad question you are asking is:
"How can I have a WinForm based UI, like-a-TabControl, with each thing-like-a-TabPage within the like-a-TabControl hosting an ActiveX control which runs in its own thread."
An interesting question ! If you care to comment, I'd like to know what you envision as the practical functionality or benefit such an architecture would enable.
A few minor comments:
1. TopMost and TopLevel are not the same creature. TopMost[^] is used to guarantee that a Form ... not a Form within a Form ... stays, while shown, in the same z-order as other Forms in the same application with TopMost=true. And other windows of your application will not be allowed to visually appear between the main form and the form(s) with TopMost = true. This is useful for 'floating' tool palettes.
And, an alternative to 'TopMost' is to set the Form.Owner property[^] of a Form (which can only be another Form): that's useful for other types of interfaces in the 'kind-of-modal' domain. ... edit ... out of order comment moved ...
Another alternative out-of-the-box way of approaching your application you may wish to explore is to modify the Program.cs file so it does not launch a Form to begin the application, but calls some function (perhaps in a static class) that launches various Forms. This technique requires you to make sure that when all Forms you've launched are closed the Application is terminated, or you will have the App running 'forever' with no UI ... edit ... this comment moved here ... where it should have placed ... I like to call this the "down with the Tyrant Main Form" architecture
That's easily done by a trivial modification of each launched Forms 'FormClosing event to examine the count of open Forms in Application.OpenForms and do the right thing if you are closing the only-one-left-standing.
So, you have a 'vast palette' of Forms related properties, and possible relationships between Forms, to work with. And you ... are the artist.
Curiousity is good !
best, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
modified 25-Oct-11 23:30pm.
|
|
|
|
|
I miss spoke. I meant to say TopLevel, not TopMost.
OK, why is this important. This is a real time trading system where each tab contains a charting component (COM object) as well as a data feed ActiveX component handling 50+ pieces of information each second. The tab panel would typically show 4 to 6 charts. Each tab represent a market GOOG, YHOO, GM for example. From a GUI stand point, the use of tabbed pages allows one to cleanly switch easily between market symbols. There is quite a bit of analytically work to be done on the data. Given I have eight threads on my PC, I want to effective run each market in its own thread as it were. Off course I realize I'm share my processes with other system and application threads.
|
|
|
|
|
I find this a fascinating scenario, and will look forward with interest to, hopefully, hearing comments on best practices for this kind of architecture from folks on this forum like Hans Dietrich, Bob Janova, Luc Patyn, Pete O'Hanlon, and Eddie Vuiggen, and many others, who are constant sources of challenge and education for this old out-to-pasture once-upon-a-time PostScript guru dabbling in .NET
To the extent you find it useful, and care to share more information on how you are managing the threads ... I'd be curious. Is this a situation where processing is being explictly done using Parallel Extensions, or using a CPU with multi-cores ?
And, does each thread have its own independent connection to some data source (internet ? dedicated something ?) in real-time, so you literally have eight 'live feeds' all coming in simultaneously ... not multi-plexed into packets ?
best, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
I certainly appreciate your interest. Regarding CPU processor, I have 4 cores and 8 threads. Intel i7 930. You are spot on the last point, each thread does have its own independent data feed.
One final note. It seems that the childforms that are created via the code I posted are referenced to the desktop. This means that the mouse pointer is offset from the chilform by the distance from the childform top left corner and the top left corner of the desktop. When you click on a childform and move the mouse it will jump. I've spent a number of hours trying to fix this problem to no avail. However, if you make the childform full docked and set it as a MDI container, you now can create childforms within this overlay form that behave correctly. Of course visually you might what to remove the top bar on forms 2 and 3, with 4 being the childform. Moreover, using the earlier tricks you can have each childform run in the thread of the parent or a new thread.
Bottom line, what we have here is really a tabControl were each tab page runs in its own thread.
|
|
|
|
|
OK, while I can see what you've done here, I would have to question why you've done it. Is it that the ActiveX components are interfering with each other being STA? Are they responsible for processing the feed? Before we can offer further advice, we really need to know why you are having to work around your controls.
|
|
|
|
|
I'm flattered to be included in that list
|
|
|
|
|
I still don't think you want the forms in separate threads. Do the market processing in separate threads, sure – since they're independent and of roughly equal processing intensity, that is a natural division of effort that makes a lot of sense to make use of the cores. But the heavy processing is in the analytics (having done a bit of trading code myself I know that the complexity of those is limited by your imagination or the ability to run within the tick speed, and speed is usually a bigger constraint) – you should be able to keep the UI all in one thread (avoiding the side effects I mentioned in my last post of a multithreaded UI) and notify it from multiple threads.
Because the data will be being touched all the time you might need to queue updates and take a non-volatile UI thread copy of the data, or use Invoke (not BeginInvoke) so that the processing is stalled while the UI update completes. This rather depends on your analytics and how much of the data you want to be visible on the UI; if the UI is just displaying the output of the analytics you shouldn't need to be too clever with update synchronisation, but if you want to see numbers (or particularly tables; DataGridViews don't take kindly to their binding source being updated) you will.
|
|
|
|
|
I think some of the responses here to what appears to be an identical design scenario to yours may be relevant:[^].
best, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
Some weeks ago I sort help achieving the following functionality:
"Dynamically create a tab-page, place a form on it running in it own thread"
I need to do this because I want each of these forms to run like a separate application within an integrated framework. The application is very time critical, handling multiple, but independent streams of data.
I thought at the time that I had found a way to do this, however, as it turned out my solution did not work reliably - do not use the code I posted previously. Sometimes it worked, other times it didn't, and in the most extreme crashed my PC. You think its working and then for no good reason it crashes; hence, why we are told the the GUI must run in the main thread. I tried many different approaches to no avail.
However, I had a stroke of luck and discovered that the order of operation is perhaps the key to cracking this nut, possibly avoiding a race condition that creates the instability. What I now have as a prototype that appears completely robust and shamelessly breaks all the rules.
The prototype application needs to be interdependently tested. That person must be expert at threaded applications. Also, this would have to be done under an NDA, they could not publish the method. I now that there are some highly talented people that participate in this forum. Contact me if interested.
|
|
|
|
|