|
Hi Experts,
I was really excited when I learned the usage of INotifyPropertyChanged interface. It made binding a bliss and the UI highly interactive and dynamic for me. But then with every problem comes a solution and more problems.
I will explain my question with an example. I have a student class.
public class Student : INotifyPropertyChanged
{
const int MINIMUM_AGE = 1;
int rollNumber = 0;
int age = 0;
string studentName = string.Empty;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
public Student() { }
public Student(string studentName, int age, int rollNumber)
{
this.StudentName = studentName;
this.StudentAge = age;
this.RollNumber = rollNumber;
}
public string Name
{
get
{
return this.studentName;
}
set
{
if (value != this.studentName)
{
if (value.Trim() == string.Empty)
throw new Exception("Name assigned does not confirms to the format. Please assign a proper alphanumeric value.");
this.studentName = value;
this.DisplayPropertyChange("StudentName");
}
}
}
public int StudentAge
{
get
{
return this.age;
}
set
{
if (value != this.age)
{
if (value < MINIMUM_AGE)
this.age = MINIMUM_AGE;
else
this.age = value;
this.DisplayPropertyChange("StudentAge");
}
}
}
public int RollNumber
{
get
{
return this.rollNumber;
}
set
{
if (value != this.rollNumber)
{
if (value < 0)
throw new Exception("Wrong value supplied. Only non negative integers allowed.");
this.rollNumber = value;
this.DisplayPropertyChange("RollNumber");
}
}
}
void DisplayPropertyChange(string propertyName)
{
if (null!=this.PropertyChanged)
{
this.PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}
}
}
So far so good. Binding to any of the property would reflect the change in the bound object.
Now, in the same class a property type is a complex/user defined type. Then how are we going to handle it.?e.g.
say in the above class the Name property is changed to the following class instead of string:
public class StudentName
{
string firstName = string.Empty;
string lastName = string.Empty;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public string FullName
{
get { return String.Concat(this.firstName," ",this.lastName); }
}
public StudentName()
{}
public StudentName(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
And I would access it with something like:
Student student=new Student();
string.Format("The student's name is {0}",student.Name.FullName);
I implemented the INotifyPropertyChanged interface in the class StudentName too. But the change is still not getting reflected automatically.
IF INotifyPorpertyChanged is not extendable for complex property is there some workaround?
Or am I overlooking some Object Oriented Concept here?
Any help will be highly appreciated.
Best Regards,
Sid
|
|
|
|
|
the simplest way will be to not implement the INotifyProperty... in the SutdentName class.
For this to work you need to implement the IEquatable<> interface
or overrdide the equals method so that the StudentClass will know how to check for equality the
StudentName objects.
In the Student Class a add a Property for the student name of type StudentName and offcourse a private field to back it up.
ex:
public StudentName Name
{
get
{
return this.studentName;
}
set
{
if (value != this.studentName)
{
if (value.Trim() == string.Empty)
throw new Exception("Name assigned does not confirms to the format. Please assign a proper alphanumeric value.");
this.studentName = value;
this.DisplayPropertyChange("Name");
}
}
}
Just an irritated, ranting son of ... an IT guy.
At your trolling services
modified on Wednesday, May 5, 2010 2:08 AM
|
|
|
|
|
Try this (pay special attention to the lines that are bolded and underlined):
public class StudentName : INotifyPropertyChanged
{
string firstName = string.Empty;
string lastName = string.Empty;
public string FirstName
{
get
{
return firstName;
}
set
{
if (firstName != value)
{
firstName = value;
this.OnPropertyChanged("FirstName");
this.OnPropertyChanged("FullName");
}
}
}
public string LastName
{
get
{
return lastName;
}
set
{
if (lastName != value)
{
lastName = value;
this.OnPropertyChanged("LastName");
this.OnPropertyChanged("FullName");
}
}
}
public string FullName
{
get
{
return String.Concat(this.firstName, " ", this.lastName);
}
}
public StudentName()
{
}
public StudentName(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
|
|
|
|
|
Hi all,
I've been trying to create a List that I want to use to populate a combo box collection. Frankly, I have no idea how to do this and have googled for quite some time trying to get a clue. Not to mention the whole List vs. IList, IEnumerable, etc. that I haven't even considered, but stumbled upon during my search. I have the code below, but I'm doing something wrong because I'm not able to call the list in a form load method.
public List<string> GetSerialDevice()
{
strPorts = SerialPort.GetPortNames();
List<string> strAmplifiers = new List<string>();
foreach (string strPort in strPorts)
{
serialPort1 = new SerialPort(strPort, 115200, Parity.None, 8, StopBits.One);
serialPort1.Handshake = Handshake.None;
serialPort1.Close();
serialPort1.ReadTimeout = 500;
serialPort1.WriteTimeout = 500;
serialPort1.Open();
serialPort1.WriteLine("!001:USR1?\r");
string strUSR1Return = serialPort1.ReadTo("\r");
if (strUSR1Return == "+2.000000")
{
serialPort1.WriteLine("!001:SERL?\r");
string strSerialLow = serialPort1.ReadTo("\r");
serialPort1.WriteLine("!001:SERH?\r");
string strSerialHigh = serialPort1.ReadTo("\r");
double dblSerialNumber = double.Parse(strSerialHigh) * 65536 + double.Parse(strSerialLow);
Console.WriteLine("On" + " " + strPort + " " + "there is a valid amplifier with S/N "
+ dblSerialNumber.ToString());
strAmplifiers.Add(dblSerialNumber.ToString());
}
}
Console.WriteLine(strAmplifiers[0]);
serialPort1.Close();
return strAmplifiers;
modified on Wednesday, May 5, 2010 12:02 AM
|
|
|
|
|
Hi,
your message isn't clear at all. The code shown is unrelated to the combobox you mention in the subject line.
and you provide no symptoms: what should it do? what does it? how is that different?
a few suggestions:
1. don't leave code in comments, in confuses all readers, including yourself.
2. don't do serialPort1.WriteLine("!001:SERL?\r"); i.e. don't mix an explicit "\r" with some implicit newline character; if you need to make sure, either set the correct value to serialPort1.NewLine or make everything explicit, e.g. serialPort1.Write("!001:SERL?\r\n");
3. what is the peripheral sending? if it includes "\r\n", what is going to happen to the "\n"? Won't it confuse the next read?
4. you should not use double.Parse as it may throw an exception on bad input; never trust an external device to always offer correct data!
5. you should provide an overall try-catch, and log the Exception.ToString() you may get. At least till you get something to work, then maybe revisit proper error handling.
6. I think you should open and close serial ports within your loop, first open, then close. Not what you did!
7. A serial open may fail (e.g. when your system has an old dial-up modem built in, you probably won't be able to open it; when it throws an exception, your foreach loop would terminate immediately!
|
|
|
|
|
Hi Luc,
Depending on your memory, you may remember that you've addressed many of these issues on previous posts of mine. As you can see, I haven't addressed these yet. I know that it is best to do as much of that up front as possible, but as a very novice C# developer, you can understand that I am happy to successfully ping all available com ports and have the S/N of the device(s) plugged in returned. I think I will have to hire someone eventually to look at what the application is doing and build a more robust one.....However, I will implement exception handling soon (as well as most of your other suggestions)
Initially, I had a question about getting a list into a combo box and the list I wanted was generated (at least attempted to) by the attached code. Specifically the instantiation of List<string>
List<string> strAmplifiers = new List<string>();
and then
strAmplifiers.Add(dblSerialNumber.ToString());
in the if loop, followed by the return statement
return strAmplifiers;
The problem I'm having is that I cannot call strAmplifiers in another method. I want to use
cboAmplifier.Items.AddRange(strAmplifiers);
but it is as if strAmplifiers wasn't returned. Apparently I have some error be it syntax or something much larger.
|
|
|
|
|
Call the method not the variable.
cboAmplifier.Items.AddRange(GetSerialDevice().ToArray());
I added ToArray because the method is returning a List<string> but the AddRange method
expects an array[] of objects.
Your strAmplifier variable/List exists only within the socpe of the Method it was defined.
Can't use the variable outside the method where it was decalred.
Just an irritated, ranting son of ... an IT guy.
At your trolling services
|
|
|
|
|
how do i do calibration for my program, as in the user key in the setting of the program.
Thanks.
|
|
|
|
|
You may want to clarify what it is you are talking about.
|
|
|
|
|
It means that i have set my actual values in the program.But i want the user to key in values to set it.
|
|
|
|
|
I still have no idea what you are talking about. If you don't want to tell anything useful, don't expect a useful answer either.
|
|
|
|
|
With the information that you provided, about the best answer your going to get is to present a TextBox to the user and let them type whatever number required into it. Then it's your just to parse the number, validate it, normalize if necessary, yada, yada, yada, ...
|
|
|
|
|
I am trying to call a program that comverts BMP to PPM formats. The exe to do so dumps the binary contents of the conversion to the console unless redirected as such
bmptoppm.exe input.bmp >output.ppm
I am attempting to call this exe from inside a different windows forms application and save the ouput to output.ppm. I am doing so using the process class
<br />
Process myProcess = new Process();<br />
<br />
myProcess.StartInfo.UseShellExecute = false;<br />
myProcess.StartInfo.Arguments = "C:\\input.bmp";<br />
myProcess.StartInfo.FileName = "C:\\bmptoppm.exe";<br />
myProcess.StartInfo.CreateNoWindow = false;<br />
myProcess.StartInfo.RedirectStandardOutput = true;<br />
myProcess.StartInfo.RedirectStandardError = true;<br />
myProcess.Start();<br />
I am getting hung on on how exactly I can do the writing of the standardoutput to a file. Could someone point me in the right direction please?
|
|
|
|
|
do something like:
SreamReader r=null;
StreamWriter w=null;
w = myProcess.StandartInput
r= myProcess.StandardOutput
from here it's just a matter of reding the output/r and saving to a specific name/path.
|
|
|
|
|
I should have been more specific. The part of saving to a specific file name/path is where I am lacking.
|
|
|
|
|
try this:
use
string str = r.ReadToEnd();
to read the whole content of the StreamReader. Now get the bytes with something like this
byte[] rawbyte= Encoding.Default.GetBytes(str);
now write the bytes to a filestream or use custom bitmap encoding.
FileStream fs = new FileStream("yourfile.here", FileMode.OpenOrCreate);
fs.Write(data, 0, data.Length);
hope it helps.
I'm not sure if it will work. Read the conversation between me and Luc bellow for
details of how ths idea came to me.
|
|
|
|
|
do you expect binary data to survive like that? I don't know, I never did that on Windows, and everything about stdin/out/err streams seems very text oriented...
|
|
|
|
|
I don't know exactly. Maybe it works maybe not. Hence the "I hope it helps".
Actually I did something like it.
We have a tracing system in our ptoduction cells and all kind of mobile scanners.
One particular kind of those scanners used to change the project comes with off
course installers. Between the drivers there's a small utility that gets the "traffic"
to and from the scanner on the particular COM port that was asigend to.
Documentation 0 nada/rien/kaput/nothing.
The program gets the human represntation of the "traffic" meaning text.
Something like: "Sending ... to COMx. ... recieved".
I had an idea in order to make it easier to use/maintain.
But that idea ment sending the bytes to the scanner.
The technigue I mentioned => Encoding.Default.GetBytes(...) where ... is the text command worked like a charm.
Hence my maybe wrong hope of working to a larger set of data/string.
PS: I'm not a prog. An IT guy. I should put that in my signature. It's empty anyways.
|
|
|
|
|
OK thanks. I hope the OP will tell us the outcome.
|
|
|
|
|
Me too.
Just an irritated, ranting sun of an IT guy
|
|
|
|
|
|
did i spelled something wrong?
Just an irritated, ranting sun of an IT guy
|
|
|
|
|
never mind I got it. It should be son not sun.
Just an irritated, ranting sun of an IT guy
|
|
|
|
|
Wow. Responses to the dome. I will attempt it and get back.
|
|
|
|
|
I have installed this from a dozen different locations and yet when I open up VS 2010 and click file, new, website there is lots of ASP.Nets there but no MVC or MVC2. Anyone know why?
Thanks
Darrall
|
|
|
|