|
Sorry about that. I've been doing so much control development lately I'm too used to such events being CancelEventHandler events (or similar)!
Yes, you'll have to throw the exception so add a handler to AppDomain.UnhandledException like I mentioned before. I recommend you also create a custom exception class that derives from ApplicationException (typically used for custom exceptions to give them a common, application-based base class) that you throw from the DataTable.RowChanging event handler. This way, you can easily just catch this exception in the handler for the AppDomain.UnhandledException event and handle appropriately, which is better than throwing such a oft-used exception and trying to determine where it came from and why it was thrown.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
I did that. And I throw a ErrorDataRowException which inherits from Application in the data table's RowChanging event.
But when the ErrorDataRowException is thrown, the application didnot enter the method UnHandledExceptionHandler. Instead, the application still popup an window in which told me there is an unhandled exception.
why? pls help me.
[STAThread]
static void Main()
{
AppDomain currentAppDomain = AppDomain.CurrentDomain;
currentAppDomain.UnhandledException += new UnhandledExceptionEventHandler(UnHandledExceptionHandler);
FormRegisterConsole fmMain = new FormRegisterConsole();
Application.Run(fmMain);
}
private static void UnHandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
if (e.GetType() == typeof(Health.ApplicationLibrary.RIS.Register.ErrorDataRowException))
{
MessageBox.Show(e.Message, "data updating", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("出现未处理错误: " + e.Message, "未处理错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
|
|
|
|
|
Try Application.ThreadException then. I use the same thing in our program I designed at work but couldn't remember which event I was using. It's been a long time since I wrote that section of the container application.
Also, just a helpful tip: try the is keyword instead of obj.GetType() == typeof(SomeClass) . It results in fewer IL instructions (better performance) and, IMO, is a little easier to read:
public static void Main(string[] args)
{
Application.ThreadException +=
new ThreadExceptionEventHandler(UnhandledException);
Application.Run(new FormRegisterConsole());
}
private static void UnhandledException(object sender,
ThreadExceptionEventArgs e)
{
if (e.Exception is ErrorDataRowException)
{
}
else
{
}
}
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
|
how to prevent changing columns' width in datagrid?
|
|
|
|
|
You could derive from DataGridColumnStyle (or one of the derivative classes to avoid extra work) and override the Width property so that the set accessor does nothing. You'll have to have an internal property or a param in the constructor so you can set the initial width, though, which you can do by setting base.Width . This works in a quick test but still allows the user to drag the splitters (just doesn't actually change the width).
Upon inspection, the members you'd need to override are both private and are not virtual, nor do they use anything relevent that is overridable.
About the only thing I can think of is to override WndProc and handle mouse messages over the column header (which you can get the bounds of through various properties), not passing those to the base.WndProc .
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
|
|
Hey, So I have some questions about technique when it comes to .net desktop development. My goal first off, is to be able to create an object on the desktop of my application and be able to pick it up and move it with the mouse. I'm convinced I could do this pretty easily using a Panel/Canvas object with a transparent background, however, I want for my objects to be non-rectangular. More precisely, polynomials of any fashion.
In Java, I used to just create an object that extended the Polygon class, and then assigned a MouseListener to it, check to see if the mouse being clicked was inside the polygon and wallah! C# and Java being so similar I would have expected this to be as well, however it does not seem so.
To elaborate, let me give an example. If anyone is experienced with diagram applications, like Visio, when you grab a line connecting two objects, you can draw it and manipulate it in almost any way you want. This can't possibly be a rectangular object. How is this done?
I'm curious about the technique used because it's something that seems a little less straight forward. However, I may be wrong. Please advise!
|
|
|
|
|
madjeux wrote:
C# and Java being so similar I would have expected this to be as well, however it does not seem so.
Just because the language syntax are similar does not mean they come with the same libraries. I'm not sure if it's possible to create a polygon and check if a point is inside it using GDI+, but it's a commonly solved problem, not so hard to do, plenty of info on the web.
madjeux wrote:
If anyone is experienced with diagram applications, like Visio, when you grab a line connecting two objects, you can draw it and manipulate it in almost any way you want. This can't possibly be a rectangular object. How is this done?
Figuring out if a point is on a specific line is very basic trig, even easier than the polygon problem. The best way to do this sort of stuff is to build a rectangle from the outermost points of the shape, quickly check if your point is inside it, and only then do the more complex test. I suggest that different objects all derive from a base class which defines abstract methods for drawing, for checking for hits, and so on. C# being too gay for multiple inheritance, you may want to derive from something else to get some other desired behaviour and define an interface for this stuff.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Ok, I gotcha. What I'm still fuzzy on is how to actually implement this in a wise way. For example, here's my code (which doesn't completely work yet).
using System;
using System.Windows.Forms;
namespace Test
{
public class Pipe : Control
{
public Pipe(){
}
protected override void OnMouseDown(MouseEventArgs e)
{
MessageBox.Show("a mouse was clicked and my object knows it");
base.OnMouseDown(e);
}
}
}
How do I add this to a form so that when a mouse is pressed, it distributes the event to my control? I was using "this.Controls.Add(new Pipe())" in initializeComponent, but it doesn't seem to work. Can someone please explain if what I am doing is retarded? Keep in mind, I am going to be adding to this class, but I just want to understand how I can have my components know when they are being clicked on. Thanks!
|
|
|
|
|
I Create The Componet myself,
i want to create my favourite Pict in the ToolBox
i search the information about it, but is show me example
below this.
// C#
// Specifies the bitmap associated with the Button type.
[ToolboxBitmap(typeof(Button)]
class MyControl : UserControl
// Specifies a bitmap file.
[ToolboxBitmap(@"C:\myImage.bmp")]
class MyControl : UserControl
[ToolboxBitmap(typeof(Button), @"C:\myimage.bmp")]
class MyControl : UserControl
how can i change the the absolute address' Picture
it means the picture include in my compont prject
in my class it like
[ToolboxBitmap(typeof(Button), @"myimage.bmp")]
class MyControl : UserControl
but how can i do
meetweb
|
|
|
|
|
When you use just a Type (the first constructor in your snippet), an image is used that has the same namespace and name as your class, but with a .bmp extension. I.e., if your class is Example.Class , then the image to be used is Example.Class.bmp . This image must be an embedded resource.
The second constructor is the name of an embedded resource, so you must include any namespace and the name of the file, like Example.Class.bmp .
The third constructor uses the namespace of the Type you pass in the first parameter and adds the name that you pass with the third constructor. If the class is Example.Class and you pass "Toolbox.bmp" as the name, then the image used is Example.Toolbox.bmp .
In all three cases, the image must be an emdedded resource, not a file on the computer. So, add a bitmap to your project, right-click and select Properties, then change the build type to "Embedded Resource".
You can find more details about this in the documentation for the ToolboxBitmapAttribute class in the .NET Framework SDK.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Has anyody experience in working with FIX? I'd need some help with understanding some general concepts.
Please let me know if anybody can help me with this
|
|
|
|
|
I have created a report using crystal reports but everytime I run it I have to type in the sql password for the database Is there any way I can save this information in the application?
TIA
------------------
Oh My goodness
|
|
|
|
|
You can keep the password in the connection string:
Provider=...; User ID=user; Password=pwd; ... This isn't very secure, but then again nothing you can store in the assembly isn't because anyone can use ildasm.exe or a similar tool to see what you have in the application.
If you're using SQL Server, perhaps a better way is to use integrated authentication, or SSPI, by excluding the User ID and Password params of the connection string and instead using Integrated Security=SSPI . This will use the credentials of the current (or impersonated) user to attach to SQL Server. The server must be configured to support mixed mode authentication, though (both SQL Server and Integrated Windows authentication).
The best practice is to not store secret information in your app because it's never secret. If you aren't using SQL Server and want you connection to be more secure, rely on either the user specifying the connection string in your application (perhaps as an option) or use ODBC.NET and let them configure their own DSN.
So, as long as this connection string is used for the DB connection for the CR report, you shouldn't have to worry about a password prompt.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
But where is the connection string located within crystal reports?
------------------
I'm naked under my clothes...
|
|
|
|
|
It's not in Crystal Reports, but required to get the data source. If you're using the CR designer, it may not give you this change and instead store it as part of the report definition. Instead, make this a two step process and bind your report to a DataSet , which you can get using a DataAdapter or something. This makes your reports a little more durable so you don't have to worry about recompiling just to change the connection string or anything like that.
To set the data source on the report, use ReportDocument.SetDataSource . When designing, there's an option to design the report bound to a strongly-typed DataSet .
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Thx for the info that helps greatly, doing that also means I can use stored procedures
------------------
I'm naked under my clothes...
|
|
|
|
|
Why isn't this working ?
conn.Open();
cmd = new SqlCommand("SPSearchRmiInfoFirstname", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Firstname", "O");
dad = new SqlDataAdapter(cmd);
dad.Fill(cpData);
rp.Load("cp.rpt");
rp.SetDataSource(cpData);
cpv.ReportSource = rp;
It doesn't display any data, am I doing something wrong
------------------
I'm naked under my clothes...
|
|
|
|
|
NeverMind I found out the problem, here is the working code.
conn.Open();
cmd = new SqlCommand("SPSearchRmiInfoFirstname", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Firstname", "O");
dad = new SqlDataAdapter(cmd);
dad.Fill(cpData.Dataset);
rp.Load("cp.rpt");
rp.SetDataSource(cpData.Dataset);
cpv.ReportSource = rp;
I forgot to pass the info of the dataset LOL
------------------
I'm naked under my clothes...
|
|
|
|
|
Here is a code example of what I want to do.
<br />
private void AdminTree_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)<br />
{ <br />
this.DisplayProperties( e.Node );<br />
}<br />
<br />
private void DisplayProperties( object inNode )<br />
{<br />
}<br />
<br />
private void DisplayProperties( QuestionNode inNode )<br />
{<br />
this.PropertiesGroupBox.Controls.Clear();<br />
<br />
this.QuestionPropertiesControl.QuestionText.Text = inNode.QuestionData.Question;<br />
this.QuestionPropertiesControl.AnswserType.Text = inNode.QuestionData.CatalogAnswerType.AnswerTypeName;<br />
this.QuestionPropertiesControl.Status.Text = inNode.QuestionData.Status;<br />
this.QuestionPropertiesControl.Dock = System.Windows.Forms.DockStyle.Fill;<br />
<br />
this.PropertiesGroupBox.Controls.Add( this.QuestionPropertiesControl ); <br />
}<br />
<br />
private void DisplayProperties( CatalogNode inNode )<br />
{<br />
this.PropertiesGroupBox.Controls.Clear();<br />
<br />
this.CatalogPropertiesControl.CatalogName.Text = inNode.CatalogData.Name;<br />
this.CatalogPropertiesControl.DisplayText.Text = inNode.CatalogData.ViewName;<br />
this.CatalogPropertiesControl.Status.Text = inNode.CatalogData.Status;<br />
this.CatalogPropertiesControl.Dock = System.Windows.Forms.DockStyle.Fill;<br />
<br />
this.PropertiesGroupBox.Controls.Add( this.CatalogPropertiesControl ); <br />
<br />
}<br />
I currently have AdminTree_AfterSelect written as follows. It works but I was wondering if anyone had any ideas on a cleaner way of doing it.
<br />
private void AdminTree_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)<br />
{ <br />
if( e.Node is QuestionNode )<br />
{<br />
this.DisplayProperties( e.Node as QuestionNode );<br />
}<br />
else if( e.Node is CatalogNode )<br />
{<br />
this.DisplayProperties( e.Node as CatalogNode );<br />
}<br />
}<br />
Thanks in advance!
|
|
|
|
|
Even though TreeViewEventArgs.Node is of Type TreeNode , the actual object is of Type QuestionNode or CatalogNode so you don't need to cast it like you're doing. For instance, even though the GetType method is inherited form Object , it will always return the Type of the actual object. I even have something similar to what you have with a massive amount of tree nodes that even have other base classes and you don't need to cast them (either using the cast operator or the as keyword). So, when you call DisplayProperties with simply e.Node , it will automatically pick the correct one because the Type is either the QuestionNode or the CatalogNode , despite the Type that TreeViewEventArgs.Node is defined as (as long as its a base class).
For example:
using System;
public class Test
{
public static void Main()
{
DisplayText(new A1());
DisplayText(new A2());
}
private static void DisplayText(A1 a)
{
Console.WriteLine("DisplayText (1): {0}", a.Text);
}
private static void DisplayText(A2 a)
{
Console.WriteLine("DisplayText (2): {0}", a.Text);
}
}
public class A
{
public virtual string Text
{
get { return "A"; }
}
}
public class A1 : A
{
public override string Text
{
get { return "A1"; }
}
}
public class A2 : A
{
public override string Text
{
get { return "A2"; }
}
} The output would be:
DisplayText (1): A1
DisplayText (2): A2
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
You are correct, but in terms of a treeview and or any of the event driven systems not quite.
Take a look at the following event handler
<br />
private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)<br />
{<br />
this.DisplayType( e.Node ); <br />
}<br />
You are passed the node from e (e.Node) and it is of type TreeNode. If you call e.Node.GetType() you will get the correct type but when used in the following context it is simply a TreeNode the base class. See method DisplayType() methods and the treeView1_AfterSelect() method.
Copy/Paste and run the following example and you will see what I mean.
<br />
using System;<br />
using System.Drawing;<br />
using System.Collections;<br />
using System.ComponentModel;<br />
using System.Windows.Forms;<br />
using System.Data;<br />
<br />
namespace test<br />
{<br />
public class Form1 : System.Windows.Forms.Form<br />
{<br />
private System.Windows.Forms.TreeView treeView1;<br />
private System.ComponentModel.Container components = null;<br />
<br />
public Form1()<br />
{<br />
InitializeComponent();<br />
<br />
<br />
TreeNodeType1 tnt1 = new TreeNodeType1();<br />
tnt1.Text = "Type 1";<br />
<br />
TreeNodeType2 tnt2 = new TreeNodeType2();<br />
tnt2.Text = "Type 2";<br />
<br />
this.treeView1.Nodes[0].Nodes.Add( tnt1 );<br />
this.treeView1.Nodes[0].Nodes.Add( tnt2 );<br />
<br />
}<br />
<br />
protected override void Dispose( bool disposing )<br />
{<br />
if( disposing )<br />
{<br />
if (components != null) <br />
{<br />
components.Dispose();<br />
}<br />
}<br />
base.Dispose( disposing );<br />
}<br />
<br />
#region Windows Form Designer generated code<br />
private void InitializeComponent()<br />
{<br />
this.treeView1 = new System.Windows.Forms.TreeView();<br />
this.SuspendLayout();<br />
this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;<br />
this.treeView1.ImageIndex = -1;<br />
this.treeView1.Location = new System.Drawing.Point(0, 0);<br />
this.treeView1.Name = "treeView1";<br />
this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {<br />
new System.Windows.Forms.TreeNode("Root Node")});<br />
this.treeView1.SelectedImageIndex = -1;<br />
this.treeView1.Size = new System.Drawing.Size(412, 393);<br />
this.treeView1.TabIndex = 0;<br />
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);<br />
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);<br />
this.ClientSize = new System.Drawing.Size(412, 393);<br />
this.Controls.Add(this.treeView1);<br />
this.Name = "Form1";<br />
this.Text = "Form1";<br />
this.ResumeLayout(false);<br />
<br />
}<br />
#endregion<br />
<br />
[STAThread]<br />
static void Main() <br />
{<br />
Application.Run(new Form1());<br />
}<br />
<br />
private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)<br />
{<br />
this.DisplayType( e.Node ); <br />
}<br />
<br />
private void DisplayType( object inNode )<br />
{<br />
MessageBox.Show(<br />
"Caught an Object",<br />
"Name Entry Error",<br />
MessageBoxButtons.OK,<br />
MessageBoxIcon.Exclamation );<br />
}<br />
<br />
private void DisplayType( TreeNodeType1 inNode )<br />
{<br />
MessageBox.Show(<br />
"Caught a TreeNode1",<br />
"Name Entry Error",<br />
MessageBoxButtons.OK,<br />
MessageBoxIcon.Exclamation );<br />
}<br />
<br />
private void DisplayType( TreeNodeType2 inNode )<br />
{<br />
MessageBox.Show(<br />
"Caught a TreeNode2",<br />
"Name Entry Error",<br />
MessageBoxButtons.OK,<br />
MessageBoxIcon.Exclamation );<br />
}<br />
}<br />
<br />
public class TreeNodeType1 : System.Windows.Forms.TreeNode<br />
{<br />
public TreeNodeType1()<br />
{<br />
}<br />
}<br />
<br />
public class TreeNodeType2 : System.Windows.Forms.TreeNode<br />
{<br />
public TreeNodeType2()<br />
{<br />
}<br />
}<br />
}<br />
<br />
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Scott Barr
Senior Software Engineer
scott@thorin.ca
http://www.thorin.ca
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
|
|
|
You're right - I constructed a bad example app that wasn't taking into account the right conditions. In this case, your original code was just fine and obviously necessary.
In the future, though, please use the <pre></pre> tags for code - it's much more readable - and specify the output condition as I did above. It certainly helps expedite the process.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|