Ok right now I have an object containing 3 strings, along with setters and getters. Now I have two questions -
First, I'm new to C# is there any way to optimize the following methods and make them more efficient?
void getSearchResults(object sender, RoutedEventArgs e)
{
string baseURL = "http://api.search.live.net/xml.aspx?Appid=<MyAPPID>&query=%22";
string companyName = ((TaxiCompany)sender).CoName;
string formatAndKey = "%22&sources=web";
WebClient c = new WebClient();
c.DownloadStringAsync(new Uri(baseURL + companyName + formatAndKey));
c.DownloadStringCompleted += new DownloadStringCompletedEventHandler(findTotalResults);
}
//Parses search XML result to find number of results
void findTotalResults(object sender, DownloadStringCompletedEventArgs e)
{
lock (this)
{
string s = e.Result;
XmlReader reader = XmlReader.Create(new MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(s)));
String results = "";
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name.Equals("web:Total"))
{
results = reader.ReadInnerXml();
break;
}
}
}
}
}
Second, I'm initializing an object - new Taxi Company (String name, String Phone, String Results). I've got name and number and I need to call the above two functions to get noOfResults so that I can initialize the object. However, I seem to run into a bunch of issues with the event handlers.
I've primarily been a web dev, so there might be something really basic I'm missing here. I have a feeling setting up the bing methods to return a string back to the constructor might be th easiest, but not quite sure how.
First of all, you don't need the lock on the main page. Then, I would say that your XmlReader block should be replaced with the LINQ-to-XML variation called XDocument, that will allow you to access the XML document with a single, elegant line:
XDocument doc = XDocument.Parse(e.Result);
Once you have the document, you can check whether it contains a specific XNode.
Related
I've had to write my first Outlook add-in.
Basically, I have two signatures to choose from: "oferta" and "default". Depending on the words contained in the mail subject, a different signature will be used.
Everything works fine with text-only signatures, but when pictures are included, these are never sent and ares displayed as blank squares instead.
However, if I manually select any of the signatures in Outlook, the pictures are properly displayed.
I guess the problem is in the GetSignature() method, which I borrowed form someone else's answer (sorry, I can't find where I got this from!).
How could I solve this? Is there a better way to automatically change the signatures?
This is my code:
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
// When an email is sent a different signature is appended depending on the subject.
private void Application_ItemSend(object Item, ref bool Cancel)
{
MailItem mail = (MailItem)Item;
string subject = mail.Subject;
string firma = subject.ToUpper().Contains("PEDIDO") ? GetSignature("oferta") : GetSignature("default");
mail.HTMLBody += firma;
if (mail != null) Marshal.ReleaseComObject(mail);
}
// Finds and returns the .htm signature file.
private string GetSignature(string signatureName)
{
string appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Signatures";
string signature = string.Empty;
DirectoryInfo diInfo = new DirectoryInfo(appDataDir);
if (diInfo.Exists)
{
FileInfo[] fiSignature = diInfo.GetFiles(signatureName + ".htm");
if (fiSignature.Length > 0)
{
StreamReader sr = new StreamReader(fiSignature[0].FullName, Encoding.Default);
signature = sr.ReadToEnd();
if (!string.IsNullOrEmpty(signature))
{
string fileName = fiSignature[0].Name.Replace(fiSignature[0].Extension, string.Empty);
signature = signature.Replace(fileName + "_files/", appDataDir + "/" + fileName + "_files/");
}
}
}
return signature;
}
}
Of course - pictures are added as separate attachments, and you never deal with them.
Also, concatenating two HTML strings (mail.HTMLBody += firma;) does not necessarily produce a valid HTML string.
If using Redemption is an option (I am its author), it exposes RDOSignature.ApplyTo method, whcih inserts a signature including its attachments and styles.
I have one variable and this variable contain multiple data.
I want to find perticuler one data so how i can find it?
my code is like
private void g1_Hold(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
{
var item=(sender as StackPanel).DataContext;
}
Here item contain multiple data like id, name ,imagepath,songpath etc.
Now i want just imagepath so how i can get it.
Help me .
Thanks in advance.
Try this one.
Hope its working if you store data in class.
private void g1_Hold(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
{
StackPanel stk = (StackPanel)sender;
ClassName sg = (ClssName)stk.DataContext;
string path=sg.imagepath;
}
Its Quite easy store data into array or list than find position of data
For example
EDIT:
ListBox lst = (ListBox)sender;
classname obj = (classname)lst.SelectedItem;
now you can use obj.anything you want
enter code hereI have got isolated storage working but it's only storing one item.
I want to be able to store a list of favourites for the user to use in a list.
At the moment, i can store loads of stops, but when i open the application again, it only rememers the last item. and deletes the rest.
private void ApplicationBarFavouriteButton_Click(object sender, EventArgs e)
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
// txtInput is a TextBox defined in XAML.
if (!settings.Contains("userData"))
{
settings.Add("userData", busStopName.Text);
}
else
{
settings["userData"] = busStopName.Text;
}
settings.Save();
MessageBox.Show("Bus Stop was added to your favourites");
}
then for displaying the list
if (IsolatedStorageSettings.ApplicationSettings.Contains("userData"))
{
listFav.Items.Add(IsolatedStorageSettings.ApplicationSettings["userData"] as string);
}
EDIT:
private void ApplicationBarFavouriteButton_Click(object sender, EventArgs e)
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
List<string> favourites = settings["favourites"] as List<string>;
if (favourites == null)
{
favourites = new List<string>();
settings.Add("favourites", favourites);
}
favourites.Add(busStopName.Text);
settings["favourites"] = favourites;
}
displaying the data
if (IsolatedStorageSettings.ApplicationSettings.Contains("favourites"))
{
listFav.Items.Add(IsolatedStorageSettings.ApplicationSettings["favourites"] as List<string>);
}
You can access your settings like you would a hash/dictionary. So if your store information in settings["bob"], you will overwrite settings["bob"] when you next store something with the same key ("bob"). In your case, you're using the key "userData", every time you use settings["userData"] = "something";, you're overwriting what is stored in that key in the settings.
You could use something like the following (I've renamed your setting to "favourites" so that it is more descriptive of it's contents):
List<string> favourites;
settings.TryGetValue("favourites", out favourites);
if (favourites == null)
{
favourites = new List<string>();
settings.Add("favourites", favourites);
}
favourites.Add(busStopName.Text);
settings["favourites"] = favourites;
and for displaying it:
if (IsolatedStorageSettings.ApplicationSettings.Contains("userData"))
{
listFav.Items.AddRange(IsolatedStorageSettings.ApplicationSettings["favourites"] as List<string>);
}
You probably need to store a generic List of type string of Stops and then read this List from the ApplicationSettings, add a new stop to the List and then store the List back to the ApplicationSettings.
I am developing a sample Twitter app for Windows phone 7. In my code to display some details of user, used the following code.
void ShowProfile()
{
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Profile_DownloadCompleted);
client.DownloadStringAsync(new Uri("http://api.twitter.com/1/users/show.xml?user_id=" + this.id));
}
void Profile_DownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{ return; }
if (e.Result == null) MessageBox.Show("NUlllllllllll");
XElement Profile = XElement.Parse(e.Result);
var ProfileDetails = (from profile in Profile.Descendants("user")
select new UserProfile
{
UserName = profile.Element("screen_name").Value,
ImageSource = profile.Element("profile_image_url").Value,
Location = profile.Element("location").Value,
TweetsCount = profile.Element("statuses_count").Value,
}).FirstOrDefault();
LayoutRoot.DataContext = ProfileDetails;
}
Here, LayoutRoot is the Grid name. But the data binding doesn't work.
Infact, when kept a Break point it seems there is no data in the ProfileDetails object. But I could observe that e.Result contains the required data in the XML format.
Can any body figureout where I am going wrong??
Thanks in advance.
You have used XElement.Parse so Profile represents the single root <user> that API request would have returned. You are then trying to look for user elements inside it which of course makes no sense.
Try XDocument.Parse instead. Also does it really make any sense assigning a IEnumerable<UserProfile> to the data context when that list can only ever contain 1 entry?
I have IQueryable object and I need to take the data inside the IQueryable to put it into Textboxs controls. Is this possible?
I try something like:
public void setdata (IQueryable mydata)
{
textbox1.text = mydata.????
}
Update:
I'm doing this:
public IQueryable getData(String tableName, Hashtable myparams)
{
decimal id = 0;
if (myparams.ContainsKey("id") == true)
id = (decimal)myparams["id"];
Type myType= Type.GetType("ORM_Linq." + tableName + ", ORM_Linq");
return this.GetTable(tableName , "select * from Articu where id_tipo_p = '" + id + "'");
}
public IQueryable<T> GetTable<T>(System.Linq.Expressions.Expression<Func<T, bool>> predicate) where T : class
{
return _datacontext.GetTable<T>().Where(predicate);
}
This returns a {System.Data.Linq.SqlClient.SqlProvider+OneTimeEnumerable1[ORM_Linq.Articu]}`
I don't see any method like you tell me. I see Cast<>, Expression, ToString...
EDIT: Updated based on additional info from your other posts...
Your getData method is returning IQueryable instead of a strongly typed result, which is why you end up casting it. Try changing it to:
public IQueryable<ORM_Linq.Articu> getData(...)
Are you trying to query for "Articu" from different tables?
With the above change in place, your code can be rewritten as follows:
ORM_Linq.Articu result = mydata.SingleOrDefault();
if (result != null)
{
TextBoxCode.Text = result.id.ToString();
TextBoxName.Text = result.descrip;
}
If you have a single result use SingleOrDefault which will return a default value if no results are returned:
var result = mydata.SingleOrDefault();
if (result != null)
{
textbox1.text = result.ProductName; // use the column name
}
else
{
// do something
}
If you have multiple results then loop over them:
foreach (var item in mydata)
{
string name = item.ProductName;
int id = item.ProductId;
// etc..
}
First, you should be using a strongly-typed version of IQueryable. Say that your objects are of type MyObject and that MyObject has a property called Name of type string. Then, first change the parameter mydata to be of type IQueryable<MyObject>:
public void setdata (IQueryable<MyObject> mydata)
Then we can write a body like so to actually get some data out of. Let's say that we just want the first result from the query:
public void setdata (IQueryable<MyObject> mydata) {
MyObject first = mydata.FirstOrDefault();
if(first != null) {
textbox1.Text = first.Name;
}
}
Or, if you want to concatenate all the names:
public void setdata(IQueryable<MyObject> mydata) {
string text = String.Join(", ", mydata.Select(x => x.Name).ToArray());
textbo1.Text = text;
}
Well, as the name suggests, an object implementing IQueryable is... Queryable! You'll need to write a linq query to get at the internal details of your IQueryable object. In your linq query you'll be able to pull out its data and assign bits of it where ever you'd like - like your text box.
Here's a great starting place for learning Linq.
I think you find the same mental struggle when coming from FoxPro and from DataSet. Really nice, powerful string-based capabilities(sql for query, access to tables and columns name) in these worlds are not available, but replaced with a compiled, strongly-typed set of capabilities.
This is very nice if you are statically defining the UI for search and results display against a data source known at compile time. Not so nice if you are trying to build a system which attaches to existing data sources known only at runtime and defined by configuration data.
If you expect only one value just call FirstOrDefault() method.
public void setdata (IQueryable mydata)
{
textbox1.text = mydata.FirstOrDefault().PropertyName;
}