|
Still getting the same error.
|
|
|
|
|
Can you post what value is coming in
e.Row.Cells[5].Text It will give a better idea on what we are dealing with.
|
|
|
|
|
|
decimal ActualFTE=Convert.ToDecimal(e.Row.Cells[5].Text);
if (ActualFTE > 1.25)
In the above code check whether e.Row.Cells[5].Text returns data that can be converted to decimal. Or add ToString() at the end and see if it helps.
decimal ActualFTE=Convert.ToDecimal(e.Row.Cells[5].Text.ToString());
|
|
|
|
|
Same error: Input string was not in a correct format.
|
|
|
|
|
Just to make sure everything is fine, try hardcoding the value and see if you still get the error.
decimal ActualFTE=Convert.ToDecimal("0.9500");
If this works without exception, then you can be sure, the problem is with the expression e.Row.Cells[5].Text . This expression you use should return some string (like your value 0.9500) that can be converted to decimal for the conversion to work without exception.
|
|
|
|
|
okay it didn't error this time but nothing changed.
|
|
|
|
|
May be the value ActualFTE is not greater than 1.25, as per your condition.
if (ActualFTE > 1.25)
{
e.Row.BackColor = Color.Red;
}
So the color will not be changed.
|
|
|
|
|
That is true for most of the 251 rows. I only see a couple that are over 1.25. So I should take out that code?
|
|
|
|
|
Do you think I should post all of my code to see if I have something missing?
|
|
|
|
|
When you want the row to be colored? Change the if condition based on that. It should work.
|
|
|
|
|
Not the whole row only that field. ActualFTE.
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI;
using System.Drawing;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
namespace StaffingWebParts.CatwComment
{
public partial class CatwCommentUserControl : UserControl
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLStaffingConn"].ConnectionString);
SqlCommand cmd = new SqlCommand();
protected void Page_Load(object sender, EventArgs e)
{
lblMsg.Text = "";
if (!Page.IsPostBack)
{
BindSubjectData();
}
}
protected void highlightrow(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
decimal ActualFTE = Convert.ToDecimal(e.Row.Cells[5].Text.ToString());
if (ActualFTE > 1.2500M)
{
e.Row.BackColor = Color.Red;
}
}
}
protected void BindSubjectData()
{
using (SqlConnection sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLStaffingConn"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = ("select a.id, b.StaffTrackingID, a.ResourceName, b. EstimateHours, EstimateFTE, b.ActualHours, b.ActualFTE,b.Comment, b.CommentBy, b.Period from StaffTracking a, StaffTrackingFTEData b where a.id = b.StaffTrackingid order by ResourceName");
cmd.Connection = sqlCon;
sqlCon.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
gvCATW.DataSource = dt;
gvCATW.DataBind();
}
else
{
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
gvCATW.DataSource = dt;
gvCATW.DataBind();
gvCATW.Rows[0].Visible = false;
}
sqlCon.Close();
}
}
}
protected void gvCATW_RowEditing(object sender, GridViewEditEventArgs e)
{
gvCATW.EditIndex = e.NewEditIndex;
BindSubjectData();
}
protected void gvCATW_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gvCATW.EditIndex = -1;
BindSubjectData();
}
protected void gvCATW_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
bool IsUpdated = false;
int StaffTrackingID =
Convert.ToInt32(gvCATW.DataKeys[e.RowIndex].Value.ToString());
TextBox ResourceName =
(TextBox)gvCATW.Rows[e.RowIndex].FindControl("txtResourceName");
TextBox EstimateHours = (TextBox)gvCATW.Rows[e.RowIndex].FindControl("txtEstimateHours");
TextBox EstimateFTE = (TextBox)gvCATW.Rows[e.RowIndex].FindControl("txtEstimateFTE");
TextBox ActualHours = (TextBox)gvCATW.Rows[e.RowIndex].FindControl("txtActualHours");
TextBox ActualFTE = (TextBox)gvCATW.Rows[e.RowIndex].FindControl("txtActualFTE");
TextBox Comment = (TextBox)gvCATW.Rows[e.RowIndex].FindControl("txtComment");
TextBox CommentBy = (TextBox)gvCATW.Rows[e.RowIndex].FindControl("txtCommentBy");
TextBox Period = (TextBox)gvCATW.Rows[e.RowIndex].FindControl("txtPeriod");
using (SqlConnection sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLStaffingConn"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = @"UPDATE StaffTrackingFTEData SET StaffTrackingID=@StaffTrackingID, EstimateHours=@EstimateHours, EstimateFTE=@EstimateFTE, ActualHours=@ActualHours, ActualFTE=@ActualFTE,Comment=@Comment, CommentBy=@CommentBy, period=@Period WHERE StaffTrackingID=@StaffTrackingID";
cmd.Parameters.AddWithValue("@StaffTrackingId", StaffTrackingID);
cmd.Parameters.AddWithValue("@EstimateHours", EstimateHours.Text);
cmd.Parameters.AddWithValue("@EstimateFTE", EstimateFTE.Text);
cmd.Parameters.AddWithValue("@ActualHours", ActualHours.Text);
cmd.Parameters.AddWithValue("@ActualFTE", ActualFTE.Text);
cmd.Parameters.AddWithValue("@Comment", Comment.Text);
cmd.Parameters.AddWithValue("@CommentBy", CommentBy.Text);
cmd.Parameters.AddWithValue("@Period", Period.Text);
cmd.Connection = sqlCon;
sqlCon.Open();
IsUpdated = cmd.ExecuteNonQuery() > 0;
sqlCon.Close();
}
}
if (IsUpdated)
{
lblMsg.Text = "'" + ResourceName.Text + "' CATW Comment updated successfully!";
lblMsg.ForeColor = System.Drawing.Color.Green;
}
else
{
lblMsg.Text = "Error while updating '" + ResourceName.Text + "' subject details";
lblMsg.ForeColor = System.Drawing.Color.Red;
}
gvCATW.EditIndex = -1;
BindSubjectData();
}
}
}
|
|
|
|
|
|
Mathi,
I was able to get it to work.
Thank you for your help and patience.
You and others have help me to complete this project.
protected void gvCATW_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (Convert.ToDecimal(DataBinder.Eval(e.Row.DataItem, "ActualFTE")) > 1.25M)
{
e.Row.BackColor = System.Drawing.Color.Red;
}
}
|
|
|
|
|
I. Consider this scenario in WinForms:
1. you decide you want to have a custom UserControl/Component implement an Interface for the usual reasons you use Interfaces.
2. since you cannot use Fields in an Interface, you implement Properties ... that's the way Interfaces work in C# / .NET.
3. in the custom UserControl/Component that inherits the Interface, you must, of course, implement those Properties the Interface specifies as 'Public ... that's the way Interfaces work in C# / .NET.
4. when you then place/drag-drop an instance of the custom UserControl/Component on a Form:
a. if you examine the Designer.cs file for the Form: you will see that Public Properties of whatever Type declared in the UserControl/Component are initialized to null ... that's the way a WinForm works.
II. How is this an issue ?
1. in the case that you wish to set the values of the Interface-specified Properties in the UserControl/Component when they are ... internally ... initialized:
a. any initialization you've done will be erased by the execution of the code in the Designer.cs file as described in 4.a.
b. you might think you can use some Event of the UserControl/Component ... like Load, or even Layout ... to initialize the Properties: you would be wrong; the code in the Designer.cs file is executed last. And, forget using 'Layout ... design-time side-effects that are "freaky."
You might think you could use the Form's ControlAdded event: sorry, that won't work.
III. why not just call the code that initializes the Properties in the UserControl/Component in the Form after the Form is initialized ... for example, in the Form's Load event ?
a. you'll have to trust me here when I say that there is a compelling reason not to do that.
IV. What is the current work-around
Fairly simple ... if you know how to use a custom ApplicationContext, and understand what that requires.
So I switched to that. Since in that application-model I create all the Forms inside a static controller-class, then it's straightforward to invoke initialization in the right sequence.
V. What I have not considered yet:
a. in the Form's Load event doing a recursive search of all Controls, and calling initialization code for each instance of the custom UserControl/Component.
VI. other thoughts
1. while I think I understand why Interfaces cannot contain Fields, why they can't have specifiers like 'ref and 'out (thanks to Eric Lippert's essays), I sometimes wonder why a property in an Interface could not have an access modifier, and why the implementation of a Property in a Class that inherits from an Interface cannot implement that Property with a 'private modifier.
I hope that when I grow up I will understand these things
So, here's a little code illustration of the above:
public interface IHasSomething
{
Dictionary<int, string> IntToString { set; get; }
}
namespace SomeNameSpace
{
public partial class SomeComponent : TextBox, IHasSomething
{
public SomeComponent() { InitializeComponent(); }
public SomeComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
this.AutoSize = true;
IntToString = new Dictionary<int, string>();
}
[Browsable(false)]
public Dictionary<int, string> IntToString { set; get; }
}
} Now assume you've compiled, and drag-dropped an instance of the custom Component onto a Form; that Form has a Button which when clicked tries to access the Dictionary implemented in the custom Component:
namespace SomeNameSpace
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
someComponent1.IntToString.Add(1,"hello");
}
}
} And, here you can see where the Dictionary was nulled out in the Designer.cs code:
this.someComponent1.IntToString = null;
«I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can't see from the center» Kurt Vonnegut.
modified 23-May-15 4:02am.
|
|
|
|
|
Hi Bill,
idea 1: Omit the setter from the interface.
idea 2: Expose only the required actions on the dictionary as methods in the interface, not the dictionary (-property).
cheers, Sascha
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Thanks, Sascha !
Omitting the 'setter is a good idea, but it also means that no external "entity" with a valid reference ... to an instance of the Class that inherits the Interface ... can set the Property ... that's a strategy I can't use in this case.Sascha Lefèvre wrote: Expose only the required actions on the dictionary as methods in the interface, not the dictionary (-property). That's a very intriguing suggestion, and one I don't quite understand: do you mean have the Interface declare method signatures for such actions as Dictionary ... 'Add, 'Remove, etc. ?
Or, could you mean ... in the Interface ... declare the signature of a method whose "only purpose" is to set the initial Value of the Property ? That would work.
In this case, I am using the Interface more as "contract" than as all-the-other-uses-possible.
I am going to think about your response, and the responses by Pete O', Richard D., and Alan N., today and so some more experimentation.
My goal here is that these Properties are initialized by a Static Class, not by any code in the Forms in which the custom Component(s) are placed/instantiated. Since, in a way, control of the instances of these custom Components, no matter what "container" they are in, is a kind of "cross-cutting concern" (to mis-use a term from the AOP religion), I do think using an ApplicationContext here may be the best way to go, and it's an alternative WinForm architecture (better to say it's the "real" WinForm architecture whether or not the programmer ever realizes that) I am very familiar with.
Have a great day (well, it's GMT +07:00 here) !
«I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can't see from the center» Kurt Vonnegut, Jr.
|
|
|
|
|
BillWoodruff wrote: do you mean have the Interface declare method signatures for such actions as Dictionary ... 'Add, 'Remove, etc. ? Exactly
BillWoodruff wrote: Or, could you mean ... in the Interface ... declare the signature of a method whose "only purpose" is to set the initial Value of the Property ? That as well, if needed. Generally I think any complex member of a class shouldn't be publicly exposed in order to be able to control which actions can be performed on it. The "Initialize"-method should therefore also ensure that it hasn't been already initialized.
Expanding on Pete's comment on separation of concerns: If that dictionary (or if it was just an example, that what it stands for) can be considered application state and your project/UI isn't trivial then I would suggest you take a look at MVC/MVP and move it from the control-class to the model. Aside from its main purpose and benefits this would also completely eliminate the issue of how to initialize the dictionary.
BillWoodruff wrote: Have a great day (well, it's GMT +07:00 here) ! Have a great day (well, evening I guess) too, Bill!
cheers, Sascha
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Thanks, Sascha, for another evocative response !
Bill: "have the Interface declare method signatures for such actions as Dictionary ... 'Add, 'Remove, etc. ? ... in the Interface ... declare the signature of a method whose "only purpose" is to set the initial Value of the Property ?" Sascha Lefèvre wrote: Generally I think any complex member of a class shouldn't be publicly exposed in order to be able to control which actions can be performed on it. I've been thinking about this ... seriously ... while taking Richard Deeming's advice and studying explicit Interface implementation.
Right now, my reason for declaring the Dictionary in the Interface is based on (what I think is) the "contractual" role of Interfaces: requiring that any Class that "claims" it can do/provide certain facilities guarantees it implements the requisite objects, methods, properties in order to compile.
If I use explicit Interface implementation, I can declare an object, like a Dictionary, in the Interface and still keep it 'private so the end-user of the Class can only access it by methods I define and publish, like 'Add, 'Remove. Like this:
public interface IRequire
{
Dictionary<string, int> RequiredDictionary { get; }
}
public class Example : IRequire
{
Dictionary<string, int> IRequire.RequiredDictionary
{
get { return this.internalDictionary; }
}
private Dictionary<string, int> internalDictionary { set; get; }
public Example()
{
internalDictionary = new Dictionary<string, int>();
}
public void AddToRequiredDictionary(string str, int i)
{
internalDictionary.Add(str, i);
}
public void RemoveRequiredDictionary(string key)
{
internalDictionary.Remove(key);
}
} So, if you have time to respond, I'd appreciate you analysis of this technique as compared to defining the Interface and Class focusing on exposing the methods:
public interface IRequire
{
void AddEntry(string key, int value );
void RemoveEntry(string key);
}
public class Example : IRequire
{
private Dictionary<string, int> internalDictionary { set; get; }
public Example()
{
internalDictionary = new Dictionary<string, int>();
}
public void AddEntry(string key, int value)
{
internalDictionary.Add(key, value);
}
public void RemoveEntry(string key)
{
internalDictionary.Remove(key);
}
} Of course, one could expose both object (Dictionary) and methods by simply combining the two implemenations shown here: would that be "over-kill" ?
I, for one, look forward to the upcoming provision in future versions of C# of method constraints: that's been mentioned in something I read recently (mabye Eric Lippert's blog ?), but I locate find the source right now.
cheers, Bill
«I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can't see from the center» Kurt Vonnegut.
|
|
|
|
|
Hi Bill!
Explicit interface implementation doesn't stop me from accessing your Dictionary - I just have to treat an instance of the Example-class explicitly as an object of a type that implements IRequire:
Example ex1 = new Example();
((IRequire)ex1).RequiredDictionary.Clear();
IRequire ex2 = new Example();
ex2.RequiredDictionary.Clear();
Explicit interface implementation is meant to solve the issue of potential member-name-collisions in case a class implements multiple interfaces. As an implication of this the members aren't visible on the implementing type but you can access them explicitly through the interface.
If you don't want the user of your class be able to perform arbitrary operations on your dictionary then you should either not include it in your interface at all (but instead methods like AddEntry and RemoveEntry; that they accomplish their task on a Dictionary would be an implementation detail of your class) or expose the Dictionary through an IReadOnlyDictionary[^]-interface (which would limit your class to .NET 4.5+) or a custom IReadOnlyDictionary-analog implementation to allow it to work with lower versions of .NET.
E.g.:
public interface IRequire
{
IReadOnlyDictionary<string, int> RequiredDictionary { get; }
void AddEntry(string key, int i);
void RemoveEntry(string key);
}
public class Example : IRequire
{
public IReadOnlyDictionary<string, int> RequiredDictionary
{
get { return new ReadOnlyDictionary<string, int>(InternalDictionary); }
}
private Dictionary<string, int> InternalDictionary;
public Example()
{
InternalDictionary = new Dictionary<string, int>();
}
public void AddEntry(string key, int i)
{
InternalDictionary.Add(key, i);
}
public void RemoveEntry(string key)
{
InternalDictionary.Remove(key);
}
}
BillWoodruff wrote: I, for one, look forward to the upcoming provision in future versions of C# of method constraints: that's been mentioned in something I read recently (mabye Eric Lippert's blog ?), but I locate find the source right now. I read about that too - I think Kent posted this recently. Yes, would be awesome I think
cheers, Sascha
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
I will study your example, and think about your remarks very carefully. thanks, Bill
«I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can't see from the center» Kurt Vonnegut.
|
|
|
|
|
BillWoodruff wrote: you must, of course, implement those Properties the Interface specifies as 'Public ... that's the way Interfaces work in C# / .NET.
Unless you use explicit interface implementation[^], in which case the interface properties won't be public members of the class.
public partial class SomeComponent : TextBox, IHasSomething
{
public SomeComponent()
{
InitializeComponent();
this.AutoSize = true;
IntToString = new Dictionary<int, string>();
}
public SomeComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
this.AutoSize = true;
IntToString = new Dictionary<int, string>();
}
protected Dictionary<int, string> IntToString { get; set; }
Dictionary<int, string> IHasSomething.IntToString
{
get { return IntToString; }
set { IntToString = value; }
}
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks Richard for that very interesting suggestion; it appear there are other reasons using explicit implementation will not work, and, when I can articulate them into clear questions/requests-for-advice, I will seek your wise council again.
As I posted (to Sascha here, today): "My goal here is that these Properties are initialized by a Static Class, not by any code in the Forms in which the custom Component(s) are placed/instantiated. Since, in a way, control of the instances of these custom Components, no matter what "container" they are in, is a kind of "cross-cutting concern" (to mis-use a term from the AOP religion), I do think using an ApplicationContext here may be the best way to go, and it's an alternative WinForm architecture (better to say it's the "real" WinForm architecture whether or not the programmer ever realizes that) I am very familiar with."
cheers, Bill
«I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can't see from the center» Kurt Vonnegut, Jr.
|
|
|
|
|
Hi Richard,
I've followed through on your suggestion to explore explicit Interface implementation, and in a detailed response to Sascha's post today: [^] there's a code example of using explicit implementation so an Object (Dictionary) is both declared in the Interface, but, still remains inaccessible from outside the instance of the Class that implements the Interface.
It "bothers" me that I still don't feel I have a "gut-level" sense of why this is working
If you have time to respond further, that would be appreciated.
«I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can't see from the center» Kurt Vonnegut.
|
|
|
|
|
While I can see where you're coming from with this Bill, a couple of thoughts occur to me.
The first is, if you want to hide the setter (for example), this should not form part of your public interface. In this case, you would omit the set from the interface, which does not prevent you from adding it in the actual implementation, it merely prevents you from calling it via your interface.
The second part is more architectural. It sounds to me like the problem you are trying to solve is most likely one that indicates that you aren't separating concerns. In other words, you are mixing the behaviour of the interface with the form. This isn't always the case, but, in most cases I've seen like this, this holds true.
|
|
|
|
|