|
If you want to use reflection (as by your title) then
object value = instanceOfClass.GetType().GetProperty("FName").GetValue(instanceOfClass, null);
That doesn't do anything different than
object value = instanceOfClass.FName;
However if you want a generic routine for saving all properties then you can do something like the following:
foreach (PropertyInfo pi in instanceOfClass.GetType().GetProperties())
{
object value = pi.GetValue(instanceOfClass, null);
}
|
|
|
|
|
Sorry, but that is not what exactly I want
What I want is that I want to apply this thing to many classes of which I don't know the properties that it contains as in....
in class1 it may be FName or LName
but what is in class 2 I don't know
I want to have some common code that will apply for all the classes I want.
the problem with this one is that here I have to call the values of all the properties individually
Please reply.
Thanks in Advance
|
|
|
|
|
Simple sample method:
public void SaveObject(object value)
{
PropertyInfo[] properties = value.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
SaveValue(propertyInfo.GetValue(value, null));
}
} Now you just call SaveObject with whatever object you want to save. Note that SaveValue will have to inspect the object to see whether it's a primitive type or a complex (e.g. TextBox ) and decide how to save it. There is a property named IsPrimitive on the Type object I think which you can use to decide what to. do.
|
|
|
|
|
'cos when I do, the type returned is:
<pre>
? _sIte_ScheduledLength.GetType()
{Name = "Int32" FullName = "System.Int32"}
[System.RuntimeType]: {Name = "Int32" FullName = "System.Int32"}
base {System.Reflection.MemberInfo}: {Name = "Int32" FullName = "System.Int32"}
Assembly: {mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
AssemblyQualifiedName: "System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Attributes: Public | SequentialLayout | Sealed | Serializable | BeforeFieldInit
BaseType: {Name = "ValueType" FullName = "System.ValueType"}
ContainsGenericParameters: false
DeclaringMethod: '_sIte_ScheduledLength.GetType().DeclaringMethod' threw an exception of type 'System.InvalidOperationException'
DeclaringType: null
FullName: "System.Int32"
GenericParameterAttributes: '_sIte_ScheduledLength.GetType().GenericParameterAttributes' threw an exception of type 'System.InvalidOperationException'
GenericParameterPosition: '_sIte_ScheduledLength.GetType().GenericParameterPosition' threw an exception of type 'System.InvalidOperationException'
GUID: {a310fadd-7c33-377c-9d6b-599b0317d7f2}
HasElementType: false
IsAbstract: false
IsAnsiClass: true
IsArray: false
IsAutoClass: false
IsAutoLayout: false
IsByRef: false
IsClass: false
IsCOMObject: false
IsContextful: false
IsEnum: false
IsExplicitLayout: false
IsGenericParameter: false
IsGenericType: false
IsGenericTypeDefinition: false
IsImport: false
IsInterface: false
IsLayoutSequential: true
IsMarshalByRef: false
IsNested: false
IsNestedAssembly: false
IsNestedFamANDAssem: false
IsNestedFamily: false
IsNestedFamORAssem: false
IsNestedPrivate: false
IsNestedPublic: false
IsNotPublic: false
IsPointer: false
IsPrimitive: true
IsPublic: true
IsSealed: true
IsSerializable: true
IsSpecialName: false
IsUnicodeClass: false
IsValueType: true
IsVisible: true
MemberType: TypeInfo
Module: {CommonLanguageRuntimeLibrary}
Namespace: "System"
ReflectedType: null
StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
TypeHandle: {System.RuntimeTypeHandle}
TypeInitializer: null
UnderlyingSystemType: {Name = "Int32" FullName = "System.Int32"}
</pre>
where _sIte_ScheduledLength is defined as:
<pre>
private Nullable<int> _sIte_ScheduledLength;
</pre>
Surely this should come back as a Nullable`1[System.Int32] ?
Many thanks!
|
|
|
|
|
typeof(Nullable<int>>).ToString returns what you expect. My guess is doing a GetType on a nullable int with a value returns the type of the underlying value.
|
|
|
|
|
Correct. It does.
Thats my problem. Completely useless, I thought.
The reason why this is a problem is that we use our own serialisation code (the .NET serializer is not strong enough). So to serialise a value, eg.
_sIte_SchecduledLength=5;
Would become:
<sIte_ScheduledLength>5</sIte_ScheduledLength>
or if it was null ...
<sIte_ScheduledLength xsi:nil="true" />
I am happy enough to serialise like this, but need to know that it was a Nullable<int> when deserializing. And since I can't get the type, to produce something like:
<sIte_ScheduledLength Type="System.Int32">5</sIte_ScheduledLength>
It sort of scuppers my plan.
Thanks for your quick response. I'd be interested if anyone else has run into/solved this problem.
|
|
|
|
|
Does this help? http://msdn2.microsoft.com/en-us/library/ms366789.aspx[^]
*edit* it appears that article doesn't help much in that it doesn't describe a way to get at the type. I remember it wasn't designed this way, but there was a big enough outcry from developers that Microsoft changed it late in Whidbey release cycle. Joe Duffy commented on this here[^].
More info on this here[^]
|
|
|
|
|
Thanks for the links. Believe it or not, I have been Googling all day!
I particularly like:
"in order to invoke GetType the compiler inserts a box operation which transforms the Nullable. We considered newslotting a GetType method on Nullable such that compilers could bind directly to that. And of course it would have merely returned typeof(T?). But many people thought this was too hackish"
from the second link ... I don't care if it is hackish - it returns the truth!
|
|
|
|
|
Yep. From your perspective, you probably wish MS never implemented this customer requested design change. But I recall lots of people getting upset over the fact that this would otherwise return false:
int? i = null;
object o = i;
bool isNull = o == null;
In respect to your problem, it appears it's not possible with the C# language! I bet if you author some IL directly you can get at the real type of a nullable value type. But it appears to be impossible from C#.
|
|
|
|
|
Dear All,
Recently i have developed an c# application under 1024/800 resolution.
But now if i run this application under 800/600 resolution the forms controls does not show in its actual size.
For this now i did not show the forms controls while i runnig this application under 800/600 resolution.
Can anybody give me solutions regarding this?
Any help regarding this geatly appreciated.
Zakir
Software Programmer
|
|
|
|
|
Make use of Anchor and Dock properties of your controls, so they resize properly with your form.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
zakir-robi wrote: the forms controls does not show in its actual size.
What does that mean???
zakir-robi wrote: Can anybody give me solutions regarding this?
Use anchor properties for your controls.
|
|
|
|
|
i'm tring to make an application that has a tab control with multiple tab pages. for integrity purposes, i want a tab page to be rendered disabled as soon as the user moves tot he next. the only problem is that there is no enabled property for tab pages and the canfocus and canselect properties are read only. Please help me!
rzvme
|
|
|
|
|
You are correct in that you cannot disable a tab page, but you can either prevent a user from going back to a previous tab page or you can allow a user to go back to a previous tab page but disable all the controls on that tab page. The sample code below will disable all controls on a previous tab.
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.SelectedIndex > highestTabIndex)
{
foreach (Control c in tabControl1.TabPages[highestTabIndex].Controls)
{
PropertyInfo pi = c.GetType().GetProperty("Enabled");
if (pi != null)
pi.SetValue(c, false, null);
}
highestTabIndex = tabControl1.SelectedIndex;
}
}
The code is the event handler for the SelectedIndexChanged event of a tab control named tabControl1. It also assumes the existence of a form level variable declared as:
private int highestTabIndex = 0;
There are some limitations of the code, for instance if you start on tabPage1 and then click tabPage3 by skipping tabPage2 the code will disable only the controls on tabPage1. You would need to check the new index versus the old index to see if they only differ by one otherwise you could select the next page. So in this example when tabPage3 was selected by skipping tabPage2 you could change the selected tab to tabPage2 and then disable tabPage1.
Tom Chester
|
|
|
|
|
Hi...
I am developing a MDI application. In that application i am creating forms dynamically, 1 per PC comport.
In each comport i am adding textbox.& i want my application should display the received data on my each comport. I have added SerialPoer.DataReceived event in my application.
But i am not able to display the received data on that dynamically created forms...
I am adding some code with this...please suggest me where i am doing mistake...
****************************************************************************************************
private SerialPort comport = new SerialPort();
TextBox tb = new TextBox();
foreach (string s in SerialPort.GetPortNames())
{
this.f1 = new VHLCOutputWindow_Form();
f1.MdiParent = this;
f1.Controls.Add(tb);
}
MY DataReceived Event-:
comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string ReceivedData = comport.ReadExisting();
f1.Controls[0].Text = ReceivedData; //i've only 1 control added on that form(i.e. TextBox tb)
}
****************************************************************************************************
right now my PC is having only 1 port...& my form is getting created but i am not able to see the data received in that form...
Regards,
Vinay
|
|
|
|
|
According to MSDN the "DataReceived event is raised on a secondary thread when data is received from the SerialPort object". Therefor your event handler runs on this secondary thread too and shouldn't/cannot access UI controls. You have to use Invoke or BeginInvoke to get around this. Take a look at the following article[^] which should be a good starting point.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
Hello All,
Does anyone know how to set the list index of a DataGridViewComboBoxColumn.
I have no problem populating and retieving the ValueMember. I just can't figure out how to set the DataGridViewComboBoxColumn to a specific item within its list.
Sounds simple right?
Your help is appreciated.
Kind Regards,
JimS
;^)
|
|
|
|
|
I am using a dataset on a table with an already defined primary key in an sql server 2000:
SqlCommand currentControllerCommand = new SqlCommand(currentControllerSQL,IDGSConnection);<br />
SqlDataAdapter currentControllerAdapter = new SqlDataAdapter(currentControllerCommand);<br />
DataSet currentControllerDS = new DataSet(); currentControllerAdapter.Fill(currentControllerDS,collector["TargetUsersTable"].ToString());
When later I try to update the table with the changes on the dataset:
SqlCommandBuilder cb = new SqlCommandBuilder(currentControllerAdapter);<br />
currentControllerAdapter = cb.DataAdapter;<br />
currentControllerAdapter.Update(currentControllerDS,collector["TargetUsersTable"]);
It tells me the following:
Error submitting changes to the Collector Database. Dynamic SQL generation for the UpdateCommand is<br />
not supported against a SelectCommand that does not return any key column information.
Why does it tell me that if I have already the primary key defined in the primary table?
Thanks for your thoughts!
mrclash
|
|
|
|
|
This is basically saying you can't autogenerate the command without primary key information.
If you want to use the CommandBuilder, you need to be aware of it's limitations.
The CommandBuilder classes can be used to build update commands for single-table select queries that include at least one unique column.
Your SQL command doesn;t include a unique column, so it cannot be used. Include the primary key in your select query, and it should work, as long as it is a single-table query. If probably looks something like this
Select col1, col2, col3 from table1 where col1 = somevalue
change it to
Select pkey, col1, col2, col3 from table1 where col1 = somevalue
If it is not a single-table query, you will need to build your own insert, update, and delete queries using the InsertCommand, UpdateCommand, and DeleteCommand properties.
|
|
|
|
|
What does the select command look like?
|
|
|
|
|
SELECT ID,Email,New FROM Collector_Users
Where ID is a primary key...
|
|
|
|
|
Hi,
Please excuse the lack of code. I don't have the source with me.
I'm builing an Server-Client based system and it's the first time I'm working with threading and socketing.
My UdpClient has a listener that's constantly waiting for incoming messages on a specific port. That listener runs on a seperate thread, which is defined in the class and the listen() method is handed as a new Threadstart.
Inside the method, the while loop checks if the application must continue listening before preparing to receive messages.
My problem is that when my application closes all the code terminates and runs out the bottom. But when I open Program Manager the process is still running and if the application starts again the port is already in use. Thus I must deduce that the listener thread did not terminate.
I tried calling the .Abort() method and it seems to work, but I can't manage to close the application completely.
My question is this: Is there a way to get a list of all threads started by my application and to terminate them manually?
Or alternatively: Is there a way I can force my application to terminate itself and all its threads?
"Build an idiot-proof application, and the world will create a bigger idiot."
|
|
|
|
|
Assign true to the IsBackground property of your thread.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
Thanks. Will try that.
Respect for 1-upping my signature...
|
|
|
|
|
OK, I did what you suggested and it worked like a charm, but I've now run into a problem of another kind.
I know that timers and multithreading don't really go together, but my app was working perfectly with 3 timers doing different things.
As soon as I made that thread background, 2 of the 3 timers stopped funtioning. They start and enable fine, but the tick event never fires.
After looking through the articles on here I can't find anything to solve my problem. Basically what I need is:
If there is no mouse movement for 20 seconds, hide a specific panel control.
Is there and easy way to do this?
|
|
|
|