|
Ummm... oookaaayyy... what does that have to do with ruppesses?
|
|
|
|
|
Hi,
How can i change color for statusbar????? winform app.
krishna
|
|
|
|
|
statusStrip1.BackColor = Color.Red;
Rajesh B --> A Poor Workman Blames His Tools <--
|
|
|
|
|
Hi,
I am wondering, is there any technique available to copy an object to another object when the objects are of different class but the signature of these classes are same (100% identical) ? For example, if I have
class A
{
public string Name;
public string EmailAddress;
}
and
class B
{
public string Name;
public string EmailAddress;
}
Now, in my code, I have a::A , b::B .
I want to copy all property values from b to a, but I have to do it manually by iterating all properties of b to a one by one like this.
a.Name = b.Name;
a.EmailAddress = b.EmailAddress;
I wish if there were any techniq to automate this task!! I know about Copy/Cloning techniques where the objects are from same class. But as you see my objects are from different class. If my class were so simply like this, I would not have worried, but my class A and B has around 50 properties which is hard to maintain. So, I would appreciate any idea.
Regards.
|
|
|
|
|
1) you could inherit from the class that has all your properties then still would be able to use reflection or cloning or etc.
2) in each class have the same sub class which will have the same properties so then pass from one to the other either by using reflection or cloning or etc.
3) one way is to use an interface. implement each property that would exist in each class and use reflection to pass the information by going after the interface in both classes.
'Never argue with an idiot; they'll drag you down to their level and beat you with experience.' ~ anonymous
modified on Thursday, August 5, 2010 9:03 PM
|
|
|
|
|
Hi,
Thanks for your reply. Actually, my classes are auto generated and I dont have control over them. I mean, my class A is a LINQ to SQL model generated from the dbml file, and class B is a proxy class for a WCF Service. Yeah, I can manipulate those classes manually but it will be hard to maintain when I will update my service reference or dbml file. So, I was looking for some other technique that can take an object of class A and return object of class B where all properties of A is copied to B.
|
|
|
|
|
ah. i would just use reflection then. get all the properites available from class A and then go through all the properties of class B. if there is a match then copy the data from A to B.
'Never argue with an idiot; they'll drag you down to their level and beat you with experience.' ~ anonymous
|
|
|
|
|
Thanks again. I am not familiar with Reflection. Would you please give me any example snippet Or point me to an article which shows how to do this task as you mentioned ?
|
|
|
|
|
Forgive...i'm a lowly VB programmer and i just quickly threw this together - so translate it and it should do what your looking for
Imports System.Reflection
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim a As New TheFromClass With {.Hello = "hello there", .Name = "myclass"}
Dim b As New TheToClass With {.GoodBye = "later dude", .Hello = "wuzup"}
Dim ta As Type = GetType(TheFromClass)
Dim tb As Type = GetType(TheToClass)
Dim obj As Object, PropertyName As String, ToPI As PropertyInfo = Nothing
MsgBox(b.Hello)
For Each FromPI As PropertyInfo In ta.GetProperties
PropertyName = FromPI.Name
obj = FromPI.GetValue(a, Nothing)
ToPI = tb.GetProperties.Where(Function(p) p.Name = PropertyName).FirstOrDefault
If ToPI IsNot Nothing Then ToPI.SetValue(b, obj, Nothing)
Next
MsgBox(b.Hello)
End
End Sub
End Class
Public Class TheFromClass
Public Property Hello As String
Public Property Name As String
End Class
Public Class TheToClass
Public Property GoodBye As String
Public Property Hello As String
End Class
'Never argue with an idiot; they'll drag you down to their level and beat you with experience.' ~ anonymous
|
|
|
|
|
Thanks a loooooooooooooot. I highly appreciate.
Yes, I know some online VB to C# converter, so this code will be fine.
Regards.
|
|
|
|
|
|
Try this:
public static void CopyFields(object source, object target)
{
if (source == null)
throw new ArgumentNullException("source");
if (target == null)
throw new ArgumentNullException("target");
FieldInfo[] fiSource = source.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
FieldInfo[] fiTarget = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fiS in fiSource)
{
foreach (FieldInfo fiT in fiTarget)
{
if (fiT.Name == fiS.Name)
{
fiT.SetValue(target, fiS.GetValue(source));
break;
}
}
}
}
Then call CopyFields(a, b) .
|
|
|
|
|
Hi Bhiller,
Thank you soooo much.. Your code will be highly useful for me.
I just checked your code and awesome!! Great !! Thats the solution what I was searching for so loooong time.
Many many thanks.
modified on Friday, August 6, 2010 2:49 AM
|
|
|
|
|
I would cache the information to make repeated calls quicker.
|
|
|
|
|
Hi,
This is looking great. Quick question, is there any way to modify this code to allow for inner class conversions too? My classes have inner classes and these too differ by name space.
I have no idea how reflection works so if you could be kind enough to point out a solution for me it would be great. If not, I'll try to figure it out :/
Thanks a lot for your time.
In life truth does not matter. What really matters is what others believe to be the truth. (The Up and Comer - Book)
|
|
|
|
|
I don't know how it works for LINQ to SQL model, but once I did something like this for Entity Framework model. For web application there was supposed to be a WCF server, that was interacting with database with help of EF. And web application wasn't supposed to reference EF libraries (cause there should be separation) and I had to do mapping between EF classes an POCO classes. And to do it I used tt scripts. They are used to generate files (different kinds of them). And with those scripts I also created some mapper, that created mappings for each class defined in the model. Maybe you can find something like this for LINQ to SQL (unfortunately I don't have time to search for it, and looking at TODO list wan't have in the nearest future).
Don't forget to rate answer, that helped you. It will allow other people find their answers faster.
|
|
|
|
|
So in an application that I am writing the main form has "IsMdiContainer" set to "True". There are a different forms for which I set the application form as the child's "MdiParent". I have these different forms working together.
For example, one form contains information about a session. In another form I have a TabControl with one tab page containing a ListView control. That ListView is supposed to contain information about "Session" objects that are associated with the current Artist (which is what the "another form" is for). The Session form also contains a few controls that hold certain information about an associated "Artist" object.
What is the best method for updating specific data on another form when the data on a form is changed? For example, the artist's name is used on the Session form and if the artist's name is changed and then saved, the necessary session forms (if visible) need to update the name as well. I currently have it doing this using code like this:
private void btnSaveArtist_Click(object sender, EventArgs e)
{
foreach (Form child in this.MdiChildren)
{
if ((child is SessionInfoForm) && (thisArtist.ContainsSession(child.Name))
((SessionInfoForm)child).UpdateArtistName();
}
}
I use "child.Name" as the parameter to "thisArtist.ContainsSession()" because a session form's name is set to the session's Unique ID (a string).
There can be more than one artist form open. And there can be more than one session form open. Each one holds the data specific to an artist or session. The reason I say only if a form is open is because, if I were to update an artist's name for session "abc123" but session form "abc123" isn't open, then I open "abc123" AFTER updating the artist, the "abc123" form pulls the information to display it.
I hope this makes sense and if it doesn't then let me know what more information you may need.
|
|
|
|
|
Without an in-depth spoken conversation about your application & design, it's hard to be sure what problem you are trying to solve. So, in lieu of that, here's how I might implement your app:
1. Have your artist class (in fact, any class whose data appears in more than one place) implement INotifyPropertyChanged .
2. Any form that modifies data must do it by assigning to a property on the object whose data it displays. You're probably doing this already. (Note - you'll need to use properties, not fields, since the event INotifyPropertyChanged exposes must be raised in a property set accessor).
3. Now, any form that presents artist information must register a handler with the event exposed by that interface; that event handler identifies what property changed and updates the UI accordingly.
By using property notify events at the 'displayed object instance' level, your main application does not need to be involved in the synchronization of content between windows. This will make the main app form 'cleaner' by reducing its responsibilities to ones that are 'application level' - namely selecting what artists/sessions to display, managing windows, etc.
Note that this architecture will cause an immediate refresh of windows showing related data - i.e. it does not wait for the data to be saved. If you want the 'to be refreshed' windows to be updated only after a save, then the the 'modifying' window will need a local copy of the object it is displaying, and must only modify the shared one when saving the new values.
Hope that helps.
|
|
|
|
|
Hello all;
I have some classes based on an interface that I need to raise events in an implementing form. However I do not want to create add an event handler definition for all the instances as in Form1_NotWhatIWant in the source sample below.
I would like to define an event handler ONCE, linked to the interface and then, any instantiated class that implements the interface will have the event handler ready.
If not an interface, can it be done through an Abstract baseclass.
I hope the query and code sample are clear enough. A clear answer is appreciated as some I found online did not explain it well. Regardsless, all help is accepted and appreciated.
Thanks
B.
public delegate void CountReachedDelegate(IBase iBase, string Message);
public interface IBase
{
Int32 Trigger {get;}
String Name { get; }
void Count(int Limit);
event CountReachedDelegate CountReached;
}
public class SubIntA: IBase
{
#region IBase Members
private int _T = 20;
public int Trigger
{
get { return _T; }
}
string _N = "A";
public string Name
{
get { return _N; }
}
public void Count(int Limit)
{
for (int x = 0; x < Limit; x++)
if (x % _T == 0)
if (CountReached != null)
CountReached(this, _N + "=" + x.ToString());
}
public event CountReachedDelegate CountReached;
#endregion
}
public partial class Form1_NotWhatIWant : Form
{
IBase A = new SubIntA();
IBase B = new SubIntB();
public Form1_NotWhatIWant ()
{
InitializeComponent();
A.CountReached += new CountReachedDelegate(CountReached);
B.CountReached += new CountReachedDelegate(CountReached);
}
void CountReached(IBase iBase, string Message)
{
listBox1.Items.Insert(0, iBase.GetType().ToString() + ": " + Message);
}
private void button1_Click(object sender, EventArgs e)
{
A.Count(100);
}
private void button2_Click(object sender, EventArgs e)
{
B.Count(150);
}
}
public partial class Form1_WhatIWouldLike : Form
{
IBase A = new SubIntA();
IBase B = new SubIntB();
public Form1_WhatIWouldLike()
{
InitializeComponent();
IBase.CountReached += new CountReachedDelegate(CountReached);
}
void CountReached(IBase iBase, string Message)
{
listBox1.Items.Insert(0, iBase.GetType().ToString() + ": " + Message);
}
private void button1_Click(object sender, EventArgs e)
{
A.Count(100);
}
private void button2_Click(object sender, EventArgs e)
{
B.Count(150);
}
}
|
|
|
|
|
I tend to write an abstract class to go with the interface.
|
|
|
|
|
So what you're wanting is to expose the event at the type level, not the instance level.
Since interfaces do not allow static members, you'll have to create an abstract base class:
public delegate void CountReachedDelegate(CountableBase countableBase, string message);
public abstract class CountableBase
{
public static event CountReachedDelegate CountReached;
public static void OnCountReached(CountableBase item, string message)
{
CountReachedDelegate del = CountReached;
if (del != null)
del(item, message);
}
public abstract void Count(int limit);
}
public class SubIntA : CountableBase
{
private int _T = 20;
public int Trigger
{ get { return _T; } }
string _N = "A";
public string Name
{ get { return _N; } }
public override void Count(int limit)
{
for (int x = 0; x < limit; x++)
if (x % _T == 0)
OnCountReached(this, _N + "=" + x);
}
}
public class SubIntB : SubIntA { }
Note that I've implemented SubIntA and SubIntB one in terms of the other. Of course, your app will be different in that regard. Depending on the degree of similarity between these classes, I'd recommend moving any count-related behavior, especially if it relates to the threshold, into the abstract base class. The aim here is to keep all related behavior in the same class (and, ideally, all behavior in a class is related to all other behavior in the class and all unrelated behavior is in another class).
BTW: your threshold check condition (x % _T == 0 ) will fire on x == 0 and on the threshold. Probably not what you want.
|
|
|
|
|
Thanks for this. I can adapt it very easily in my project.
|
|
|
|
|
I have an application that spits out binary masks to file. These files are simply a long string of bits, each set to 1 or 0. There is no metadata or header; you need to know the dimensions of the mask before processing it. I would like to convert these files into bitmaps for each of visualization.
I have code that works, but it's extremely inefficient (40 seconds for a 1025x1025 pixel image). This mechanism runs through the bits one at a time, tests each one and sets the bits of a bitmap individually to black or white based on the test result. Can anyone suggest a more efficient method?
public static void FileToImage(string path)
{
byte[] data;
using (FileStream fs = File.OpenRead(path))
{
data = new byte[fs.Length];
ReadWholeArray(fs, data);
}
int i = 0;
int numPixels = 1025;
Bitmap bmp = new Bitmap(numPixels, numPixels);
for (int y = 0; y < numPixels; y++)
{
for (int x = 0; x < numPixels; x++)
{
if (data[i++] == 0)
{
bmp.SetPixel(x, y, Color.Black);
}
else
{
bmp.SetPixel(x, y, Color.White);
}
}
}
bmp.Save(path + ".bmp");
}
private static void ReadWholeArray(Stream stream, byte[] data)
{
int offset = 0;
int remaining = data.Length;
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0)
throw new EndOfStreamException
(String.Format("End of stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;
}
}
|
|
|
|
|
How about creating a bitmap with a white background, and only add the black spots?
..if you only need to add black spots, and an entire row in the matrix consists of "black spots", would it be feasible to draw an entire line, as opposed to dots?
OTOH, think you might also be able to convert it to a memorystream, and try to instantiate a bitmap from that stream.
Time for some sleep, curious what other solutions appear on this question
I are Troll
|
|
|
|
|
Never use GetPixel or SetPixel if it has to be fast. Use LockBits and unsafe code instead. It's several orders of magnitude faster for reasonable bitmap sizes (anything larger than just a couple of pixels).
|
|
|
|
|