I do have a CodeFunction object from EnvDTE namespace. I do want to get the definition of it; e.g.:
private void MenuItemCallback(object sender, EventArgs e)
{
MessageBox.Show("Try");
}
I would like to get first line as string.
What I have tried until now,
1 ) Try to make a string by getting CodeFunction's Type (return type) and Parameters then in a loop add them to a string. However, parameter types' names become like "System.UInt32" etc. which I don't want to. Also a problem with this, it may not take ref Guid pguidCmdGroup as fully. I am afraid of skipping ref at this.
2 ) I tried to use functions of CodeFunction but all I could get was simple name of it.
3 ) I tried to write from starting point and ending point of the CodeFunction but couldn't find a way to turn two TextPoint to string and as I realized ending point is not the ending of the definition but the function it self which I don't want to.
How can I get just simply private void MenuItemCallback(object sender, EventArgs e) or MenuItemCallback(object sender, EventArgs e)?
Thanks for all your help.
You must use GetStartPoint() and GetEndPoint() :
Read the full source of the function and then cut off the
code before the first open curly brace.
// Retrieve the source code for the function.
TextPoint start = codeFunction.GetStartPoint(vsCMPart.vsCMPartHeader);
TextPoint finish = codeFunction.GetEndPoint();
string fullSource = start.CreateEditPoint().GetText(finish);
// Find the first open curly brace
int openCurlyBracePos = fullSource.IndexOf('{');
string declaration = String.Empty;
if (openCurlyBracePos > -1) {
declaration = fullSource.Substring(0, openCurlyBracePos).Trim();
}
Related
I use GPS data and NMEA sentences.Even I only want to see and save the sentences which begins with "$GNGGA" and "$GNTVG" in my richtextbox, there are other sentences(lines) begining with different codes($GNGLL, $GLGSV, $GPGSV etc). What should I do to only get "$GNGGA" and "$GNTVG" sentences to Richtextbox?
Here is my code;
string[] gParca;
string gKG, gDB, gUydular, gYukseklik, gEnlem, gBoylam, gYataySapma, gKilitlenme, gVelocity, gSaat;
private void GPSVelocity(string NMEA2)
{
gParca = NMEA2.Split(new char[] { ',' });
switch(gParca[0])
{
case "$GNVTG":
gVelocity = gParca[7];
break;
}
private void GPSDataBilgisi(string NMEA)
{
gParca=NMEA.Split(new char[] { ',' });
switch (gParca[0])
{
//Global Positioning System Fix data
case "$GNGGA":
gParca[2] = gParca[2].Replace('.', ',');
gParca[4] = gParca[4].Replace('.', ',');
}
}
private void serialPortGPS_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
GPSDataBilgisi(serialPortGPS.ReadLine());
GPSVelocity(serialPortGPS.ReadLine());
}
private void GPSVel(string NMEA2)
{
if(checkBoxSave.Checked)
{
richTextBoxGPSData.AppendText(NMEA2);
}
}
private void GPSData(string NMEA)
{
if(checkBoxSave.Checked)
{
richTextBoxGPSData.AppendText(NMEA);
}
}
Disclaimer
As per OP's reply to my question, I am assuming serialPortGPS.ReadLine() works exactly like TextReader.ReadLine().
Since you want to filter the input you are getting, add a filter to the function that retrieves the data.
private void serialPortGPS_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
for(int i = 0; i < 2; i++)
{
string line = serialPortGPS.ReadLine();
if(line.StartsWith("$GNGGA"))
GPSDataBilgisi(line);
if(line.StartsWith("$GNVTG"))
GPSVelocity(line);
}
}
If the line starts with anything else (e.g. "HELLOIAMALINE"), neither if-check will pass and the code will not do anything with the line, it just moves on to the next one.
You can remove the switch statements in your code, they are no longer needed (of course keep the logic that is inside them!)
There are some caveats here, because I think your code and intention is a bit vague. If you can clarify any of these, I can update my answer.
Going by your question, I assume you do not want to call ReadLine() exactly twice (once for each method). I infer that you want to read every line individually (because that's how TextReader usually works), check if it starts with a "good" value, and then execute the function that needs it.
My original example specifically reads 2 rows and parses them. If you are instead trying to read all lines from the gps update, change the code as follows:
private void serialPortGPS_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string line;
while((line = serialPortGPS.ReadLine()) != null)
{
if(line.StartsWith("$GNGGA"))
GPSDataBilgisi(line);
if(line.StartsWith("$GNVTG"))
GPSVelocity(line);
}
}
Part of me wonders if reading directly from serialPortGPS is the correct approach. This is pure speculation, but I would expect your SerialDataReceivedEventArgs e to contain a property with the newly received data. It's not impossible that what you are currently doing is correct, but it is more unusual than using the event args that you receive from the update event.
You could use LINQ to immediately filter out the rows that you need (instead of having to manually iterate over them). However, Textreader implements a pattern where it only processes one line at a time (similar to yield return). If you use LINQ, you're going to end up processing all lines at the same time when you want to filter them. If you need to process line by line (e.g. because the data you're processing has a huge memory footprint), then you should avoid LINQ
If you want an example of LINQ:
List<string> theLinesThatIWant =
allTheLines.Where(line => line.StartsWith("$GNGGA")).ToList()
But like I said, only use this if you are able and willing to have all the data in memory at the same time.
So I'm totally new to C# and I've been building a "Character Generator" for a tabletop RPG. I've assigned a button with the task of generating a new story every time it is pressed. I've downloaded a huge collection of character portraits which I'd like to display in this little app of mine to give some inspiration to the user.
I thought that using a button I could have the app select a different image in the aforementioned list every time it is pressed.
I tried this:
private void button1_Click(object sender, EventArgs e)
{
List<String> paths = new List<String>();
Random random = new Random();
paths.Add(Project1.Cartes.Portrait);
pictureBox1.ImageLocation = paths[random.Next(0, images.Count - 1)];
I get two errors: Project1.Cartes.Portrait is an invalid namespace, and the name "images" does not exist.
I can't mention every image, since there are 500 of them. So I need the app to instead take a random image from a specific location. Any ideas ?
There is insufficient code be definite, however, the errors do indicate exactly what's wrong. For example, where is the variable images defined, what type is it, and how it is initialised? Also, I assume that Project1.Cartes.Portrait is meant to be a list of paths to the images and should there for be defined as List<string> somewhere within the current namespace.
As I noted in my comment, I think the Project1.Cartes.Portrait is not what you expect it to be. It should be a List<string> to any image files on your disk but it might add the string representation to your paths list.
Something like:
System.Collections.Generic.List1[System.String] (which is definitively not a path to an image file)
instead of the expected:
C:\mypath1.jpg
C:\mypath2.jpg
C:\mypath3.jpg
So please stop the debugger with a breakpoint after paths.Add(Project1.Cartes.Portrait) and check if your variable paths is what you expect it to be.
Btw, if Project1.Cartes.Portraitpoints to a real List<string>, you should use paths.AddRange(...) instead of paths.Add(...) to add the string contents from the list instead of the list itself.
Store the image's locations while your form is loading. Also, you need to remove image use bellow instead.
pictureBox1.ImageLocation = paths[random.Next(0, paths.Count - 1)];
Here is the full code. Just need to store the file names in the list.
List<String> paths = new List<String>();
private List<string> GetPaths()
{
//You can get it anywhere
throw new NotImplementedException();
}
private void Form1_Load(object sender, EventArgs e)
{
paths = GetPaths();
}
private void button1_Click(object sender, EventArgs e)
{
Random random = new Random();
pictureBox1.ImageLocation = paths[random.Next(0, paths.Count - 1)];
}
It might be easy but im stuck!
i do have a class that Create one Command for me like:
As you can see this Encode will Return me bCommand!
Now im having a Button Function that i should call this bCommand and Assign it as a Value like:
So i got the Error that Bcommand Does not Exist in Current Context
I'm looking for any advice how i can Solve the Problem.
You need to assign the results of the Encode method to a variable.
private void btnModel_Click(object sender, EventArgs e)
{
byte[] bCommand = Encode("C11", "");
WriteData(bCommand); // bCommand will now exist in this context
}
I have something to do under a button click (add values to listbox) only if a particular string changes from its previous value. How do I manage this? Below is a sample of my code:
private void button6_Click(object sender, EventArgs e)
{
string x = //some varying value I get from other parts of my program
listBox1.Items.Clear();
listBox1.Items.Add(x + /*other things*/);
}
I can at times have same value for string x from previous value when clicking button6. In such cases I don't want listBox1 to add the item (string x). How to add to listbox only when value of string changes? There's no way to predetermine string x. It gets value when program is running.
Note: adding values to listBox1 every single time and later deleting the duplicates wont work in my program.
Have you considered keeping a copy of the old string value around in a private field, and simply comparing the new value to the old value to see if they match?
For example:
// holds a copy of the previous value for comparison purposes
private string oldString = string.Empty;
private void button6_Click(object sender, EventArgs e)
{
// Get the new string value
string newString = //some varying value I get from other parts of my program
// Compare the old string to the new one
if (oldString != newString)
{
// The string values are different, so update the ListBox
listBox1.Items.Clear();
listBox1.Items.Add(x + /*other things*/);
}
// Save the new value back into the temporary variable
oldString = newString;
}
Edit: As the other answers suggest, there are certainly other, more complicated solutions, like encapsulating all access to the string value in a property, or wrapping the string in a custom class. Some of these alternatives have the potential to be "cleaner", more object-oriented approaches. But they're all more complicated than simply saving the previous value in a field. It's up to you to decide whether your specific use case merits the complicated solution, or a simpler one. Think about long-term maintainability, not what's easier for you to implement right now.
string last = string.Empty;
private void button6_Click(object sender, EventArgs e)
{
string x = //some varying value I get from other parts of my program
if(x!=last)
{
listBox1.Items.Clear();
listBox1.Items.Add(x + /*other things*/);
last = x;
}
}
If this string is super important and gets passed around alot, maybe you should wrap it in a class. The class can hold the string value as a property, but also keep track of when it has changed.
public class StringValue
{
private bool _changed;
public string StrValue{get; set{ _changed = true;}
public bool Changed{get;set;}
}
this is rudimentery of course
I'm not sure I understand completely, but it sounds like you should be using a property to set String x;
string _x = string.Empty;
public string X
{
set
{
if(value != this._x)
{
DoFancyListBoxWork();
this._x = value;
}
}
get
{
return this._x;
}
}
If this is web application, store your last value into session variable. If this is windows application, store it at a class level variable or in singleton class and use this last value for comparison with new value.
On the page load add the current value to viewstate and at the button click check the current value is equal to the value in the view state. If both are equal we can say that the value is not changed.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["CurrentValue"] = Your Value;
}
}
protected void btnSubmit_click(object sender, EventArgs e)
{
if (NewValue== ViewState["CurrentValue"].ToString())
{
lblmsg.Text = "value is not changed..";
return;
}
else
lblmsg.Text = "value is changed..";
}
You can check the detailed article in this link.
Check Control Value is changed or not
First, I'd like to ask you to check most of the other answers. They are more complete, in that they treat more global issues of tracking the changes of a variable.
Now, I'm assuming, from reading the snippet of code you provided, that you need to track if a string was changed by the user. So, in other words, you probably have a TextBox or other kind of control through which the user can change that value. This is where you should focus your attention: just consume the TextChanged event.
If, however, I'm mistaken and your string comes from any other kind of external source, either use the wrapper class suggested by #Ryan Bennett or, if you are using .Net 4, use a dynamic container, which raises a PropertyChanged event whenever any property is changed.
I can't find a solution for this problem:
I write a program, which reads all file in a directory and puts them in a listbox.
When a user select a file from a listbox, the program reads the selected file and prints out some info...
The problem is that after the firs selection my program "stop working". He don't crash, but when I try to select another file he do nothing.
I figured out, that the problem is in:
private String porocilo(String s)
{
file = "/path to file/";
TextReader tr = new StreamReader(file); //<- problem here
//...
tr.close();
return someinfo;
}
//..
//Call function:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = porocilo(listBox1.SelectedItems[0].ToString());
}
After removing that (problem) line the program normally select files, but without this I can't read files and my program don't do anything.
Can someone tell me where I'm wrong?
Br, Wolfy
If the code you posted is really the code you are using (plus the missing semicolon), then the reason you are not seeing anything happening is because your code keeps opening and reading the same file, not the file the user selected. You are setting file to a constant path/filename and read from that, and you are not making use of the s parameter.
It looks like you have a hard-coded path in your porocilo method. That is, new StreamReader is taking as it's argument, file, not s.
So it will only ever open, one file, not the file you selected.
private String porocilo(String s)
{
//file = "/path to/file" // not sure what this is...???
TextReader tr = new StreamReader(s); //<- fix here
//...
tr.close();
return someinfo;
}
In your List box Selected index change method you need to assign the selected value as shown below
//Call function:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = porocilo(listBox1.SelectedItem.Text);
}
Also check your "porocilo" function it uses the parameter corectly