event using for autoupdate - c#

I have this small code on c# .NET which publish tweets and shows timeline of twitter using tweetinvi . And I'd like to autoupdate timeline whenever the tweet is sent. Can anyone advice how to do it with event? Thanks for answers.
private void button1click(object sender, EventArgs e)
{
if (richTextBox1.Text != "")
{
Tweet.PublishTweet(richTextBox1.Text);
MessageBox.Show("Your tweet was sent!", "Important Message");
}
else
{
MessageBox.Show("You need to write something!", "Important Message");
}
}
private void Timeline_GetHomeTimeline(object sender, EventArgs e)
{
var loggedUser = User.GetLoggedUser();
string x = "";
var homeTimelineTweets = loggedUser.GetHomeTimeline();
foreach (var tweet in homeTimelineTweets)
{
x += tweet.Text + Environment.NewLine;
}
richTextBox2.Text = x;
}

First of all please note that it is a very bad practice to make several calls User.GetLoggedUser();. The reason being that the endpoint is limited to 15 requests every 15 minutes (1 per minute).
If the user happens to publish more than 15 tweets in 15 minutes, your code will break.
Now you have multiple solutions to solve the problem, but the best one is the UserStream (solution 1).
Solution 1
I would suggest to add the following code in the Initialized event.
var us = Stream.CreateUserStream();
us.TweetCreatedByMe += (sender, args) =>
{
// Update your rich textbox by adding the new tweet with tweet.Text
var tweetPublishedByMe = args.Tweet;
// OR Get your timeline and rewrite the text entirely in your textbox
var userTimeline = Timeline.GetHomeTimeline();
if (userTimeline != null)
{
// foreach ...
}
};
us.StartStreamAsync();
Solution 2
If you do not need to reload your Timeline each time the user publishes a tweet but you do need the new tweet to be displayed use the following solution.
var tweet = Tweet.PublishTweet("hello");
if (tweet != null)
{
// Update your rich textbox
}
Solution 3
Update your timeline if a tweet has been published successfully.
var tweet = Tweet.PublishTweet("hello");
if (tweet != null)
{
var userTimeline = Timeline.GetHomeTimeline();
if (userTimeline != null)
{
// foreach ...
}
}
NOTE Please note that I have never had the need to retrieve the LoggedUser at any point. Most of the time a LoggedUser should be retrieved once and then used across your app.
Also please note that I am the main developer of Tweetinvi.

Related

WebClient on Store Universal Apps

I'm using this code on Windows Desktop App to get the values of a combobox that I after need to select which is going to update the page with new information using JavaScript
private WebBrowser withEventsField_wb;
WebBrowser wb {
get { return withEventsField_wb; }
set {
if (withEventsField_wb != null) {
withEventsField_wb.Navigated -= navigated;
}
withEventsField_wb = value;
if (withEventsField_wb != null) {
withEventsField_wb.Navigated += navigated;
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
wb = new WebBrowser();
wb.Navigate("https://academicos.ubi.pt/online/horarios.aspx?p=a");
}
private void navigated()
{
HtmlElementCollection allelements = wb.Document.All;
HtmlElement year = default(HtmlElement);
foreach (HtmlElement webpageelement in allelements) {
if (webpageelement.GetAttribute("id").Contains("ContentPlaceHolder1_ddlAnoLect") == true) {
year = webpageelement;
HtmlElementCollection yoptions = year.Children;
foreach (HtmlElement yopt in yoptions) {
ComboBox1.Items.Add(yopt.InnerText);
}
}
}
}
But now I'm trying to do the same on Universal App (Windows Phone/Windows) but I'm being unable to do the same. I know that I have to use HttpClient but it does not work like a WebBrowser, this web browser is only created by code to get all the data needed and as for each step of data that I need to retrieve the website does not refresh normally but uses jQuery to load the new information.
Any help?
Well after a lot of searching I got something that helps and even gave me other idea
http://blog.gauravchouhan.com/tag/advance-web-scraping-using-c/

How to fetch all the data from the contacts in a Windows Phone app?

I want to have the names and pictures of all the contacts and store it somewhere? How can we do that? From what I have found, it is only allowing to search for one and get its details.
You access Contact Data on WindowsPhone using the Microsoft.Phone.UserData namespace, here's a full article about achieving that How to access contact data for Windows Phone, However if you wanna go little bit further in Creating Contacts, try the ContactStore class it has many methods that help you do what you want.
Update :
if you want to get all contacts :
First declare using Microsoft.Phone.UserData;
Use the following code to fire and subscribe to the search :
code :
private void ButtonContacts_Click(object sender, RoutedEventArgs e)
{
Contacts cons = new Contacts();
//Identify the method that runs after the asynchronous search completes.
cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(Contacts_SearchCompleted);
//Start the asynchronous search.
cons.SearchAsync(String.Empty, FilterKind.None, "Contacts Test #1");
}
void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
/* Here use the e.Results to return an object of type QueryDataEnumerable<Microsoft.Phone.UserData.Contact> where you can enumerate through the contacts returned*/
}
Using the Asynchronous method SearchAsync with String.empty and FilterKind.None just returns all the contacts you have on your phone it returns an object of type QueryDataEnumerable<Microsoft.Phone.UserData.Contact> which you can loop through and use each contact separately.
I hope this is what you are looking for.
Update 2 :
the ContactQueryResult.GetContactsAsync() you are trying to use works with the ContactStore Class which helps you create a custom contact store for your app. When you save contacts to this store, they will appear on the phone’s People hub, integrated with the user’s other contacts ... (see full article), and I don't think that helps your case, I think using what's already mentioned in this answer , will give you the ability to get all contacts you want, and consume them as you want.
Update 3 :
use such a code in the Contacts_SearchCompleted method to get the picture of a contact
Stream s = ((Contact)e.Results.First()).GetPicture();
You should start with a reading on Contact filtering and matching in msdn. For code snippet, check How to access contact data for Windows Phone.
For example a sample from msdn to count this items :
private void ButtonContacts_Click(object sender, RoutedEventArgs e)
{
Contacts cons = new Contacts();
//Identify the method that runs after the asynchronous search completes.
cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(Contacts_SearchCompleted);
//Start the asynchronous search.
cons.SearchAsync(String.Empty, FilterKind.None, "Contacts Test #1");
}
void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
//Do something with the results.
MessageBox.Show(e.Results.Count().ToString());
}
Don't forget to add the ID_CAP_CONTACTS capability in your app's manifest and a using Microsoft.Phone.UserData; to your code.
Update :
For example if you want every name of your contacts :
void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
IEnumerable<Contact> contacts = e.Results; //Here your result
string everynames = String.Empty;
foreach (var item in contacts)
{
//We can get attributes from each item
everynames += item.DisplayName + Environment.NewLine;
}
MessageBox.Show(everynames);
}
Update 2 :
For example if you want name, first mail and first number, you could use a code like this :
void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
IEnumerable<Contact> contacts = e.Results; //Here your result
string everynames = String.Empty;
foreach (var item in contacts)
{
//We can get attributes from each item
everynames += item.DisplayName + ";" //Get name
+ (item.EmailAddresses.Count() > 0 ? (item.EmailAddresses.FirstOrDefault()).EmailAddress : "") + ";" //Check if contact has an email. If so, display it. He can be more than one !
+ (item.PhoneNumbers.Count() > 0 ? (item.PhoneNumbers.FirstOrDefault()).PhoneNumber : "") + ";" //Check if contact has a phonenumber. If so, display it. He can be more than one !
+ Environment.NewLine;
}
MessageBox.Show(everynames);
}
Update 3 :
If you want all pictures, I will share you an example. Don't forget to check the doc :
void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
foreach (var result in e.Results)
{
var stream = result.GetPicture();
if (stream != null)
{
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(stream); // You can do a list of image if you want to.
Image img = new Image();
img.Source = bmp;
stack.Children.Add(img); // I choose to display in a stackpanel
}
}
}
Don't forget to try {} catch {}
You can change FilterKind in SearchAsync(). We use FilterKind.None to get everything.

Saving data to database using linq

I face problems with my codes about saving data into database. I have a Text box and a Combo box but when I key in data in the Text box and select data in the Combo box and click save, nothing happens and no error were found during compiling. Can I know what actually went wrong and give me some solution to it?
enter code here private void btnCreate_Click(object sender, EventArgs e)
{
using (testEntities Setupctx = new testEntities())
{
string selectST = cbSeats.SelectedItem.ToString();
string inputST = txtStation.Text;
var createStation = (from createST in Setupctx.stations
where createST.Seats == selectST
where createST.Station1 == inputST
select createST).SingleOrDefault();
if (createStation != null)
{
Setupctx.stations.AddObject(createStation);
Setupctx.SaveChanges();
txtStation.Text = "";
MessageBox.Show("New Station Has Been Created.");
}
}
}
Your help will be greatly appreciated.
I'm agreeing with #JamesD on making sure the event handler is called.
Additionally, when you get an object from a linq query and make changes to it, you need to save those changes it by calling SubmitChanges() on the DataContext. (I'm assuming that Setupctx is a DataContext object).
Read here for information on SubmitChanges()
Also, I don't know if you are using SQL or not. If so, here is a great tutorial: Linq to SQL Tutorial
You need to create a new station object like this:
if (createStation != null)
{
var obj = new Staion();
obj.Seats=selectST;
obj.Staion1=inputST;
Setupctx.Staions.Add(obj);
Setupctx.SubmitChanges();
txtStation.Text = "";
MessageBox.Show("New Station Has Been Created.");
}
More on LINQ To SQL here
This is the right way of doing it.
private void btnCreate_Click(object sender, EventArgs e)
{
using (testEntities Setupctx = new testEntities())
{
string[] stations = StationNameList();
station creStation = new station();
creStation.Station1 = txtStation.Text;
creStation.Seats = cbSeats.SelectedItem.ToString();
if (stations.Contains(txtStation.Text))
{
MessageBox.Show("This Station is already been created. Please enter a new Station.");
}
else
{
Setupctx.stations.AddObject(creStation);
Setupctx.SaveChanges();
txtStation.Text = "";
cbSeats.SelectedIndex = -1;
MessageBox.Show("New Station Has Been Created.");
}
}
}
Just to check off the list:
Have you made sure the button event handler is hooked up?
When you say
nothing happens
Do you mean the event handler is not called? You're not actually doing anything with the station you've retrieved from the database either. You're adding it back in to the stations list that you've pulled it out from.

How to update text in a label

I have here a long method that takes a little while to execute. I would like to keep the user entertained so I created a progress bar and a label. What I would like is for that label to change while the system executes the progress. Ive been looking at Application.DoEvents(), but it seems like thats the wrong way to go. This application is pretty simple and its just a project and nothing professional. All this app does is send a file to a client and insert the data into a database.
I have one label (besides a success and error label), that I would like to constantly update along side the progress bar. Any ideas or tips on how to do this? Would Application.DoEvents() be acceptable in this situation? Or is there a simple way to update the text. I am using C#, asp.net, and a System.Web.UI.Page. Any help or pointing me to the right direction would be greatly appreciated.
protected void Button_Click(object sender, EventArgs e)
{
PutFTPButton.Enabled = false;
Thread.Sleep(3000);
Button btn = (Button)sender;
KaplanFTP.BatchFiles bf = new KaplanFTP.BatchFiles();
KaplanFTP.Transmit transmit = new KaplanFTP.Transmit();
//label text change here
if (btn.ID == PutFTPButton.ID)
{
//bf.ReadyFilesForTransmission();
DirectoryInfo dir = new DirectoryInfo(#"C:\Kaplan");
FileInfo[] BatchFiles = bf.GetBatchFiles(dir);
bool result = transmit.UploadBatchFilesToFTP(BatchFiles);
//label text change here
if (!result)
{
ErrorLabel.Text += KaplanFTP.errorMsg;
return;
}
bf.InsertBatchDataIntoDatabase("CTL");
bf.InsertBatchDataIntoDatabase("HDR");
bf.InsertBatchDataIntoDatabase("DET");
bf.InsertBatchDataIntoDatabase("NTS");
List<FileInfo> allfiles = BatchFiles.ToList<FileInfo>();
allfiles.AddRange(dir.GetFiles("*.txt"));
bf.MoveFiles(allfiles);
//label text change here
foreach (string order in bf.OrdersSent)
{
OrdersSentDiv.Controls.Add(new LiteralControl(order + "<br />"));
}
//lblWait.Visible = false;
OrdersSentDiv.Visible = true;
OrdersInfoDiv.Visible = false;
SuccessLabel.Visible = true;
NoBatchesToProcessLbl.Visible = true;
BatchesToProcessLbl.Visible = false;
PutFTPButton.Enabled = false;
BatchesCreatedLbl.Text = int.Parse(NextBatchNum).ToString();
Thread.Sleep(20000);
if (KaplanFTP.errorMsg.Length != 0)
{
ErrorLabel.Visible = true;
SuccessLabel.Visible = false;
ErrorLabel.Text = KaplanFTP.errorMsg;
}
}
}
I think you can use an Ajax UpdateProgress control, check Progress Bar on File Upload ASP.NET.
EDIT: Another one Displaying Progress Bar For Long Running Processes using ASP.NET AJAX.
Application.DoEvents() is not available in an ASP.NET application, nor is it's use acceptable in a standard WinForms application with the advent of multicore processors and the .NET threading library.
A web application requires communication to/from a server. Therefore simply updating the text of a label does nothing unless you are sending that back to the client. In your case you would need an event which was signaled by this line (because it is a batch upload):
transmit.UploadBatchFilesToFTP(BatchFiles);
The event would update the value you want to display. You would then need some AJAX code (or an ASP.NET update panel around a ASP.NET label) on the web page in question to get and display the new value.
HTH
delegate void SetTextCallback(string text);
private void SetText(string text)
{
if (this.label1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else this.label1.Text = text;
}
void SomeMethod()
{
SetText(yourVariable.ToString());
}
if i understand you correctly this should work.

Modifying Quartz.NET job details after they've been scheduled

I have a Quartz.NET application where I need the administrators to be able to modify the job details - mostly information in each jobs datamap, but also things like the triggers - here is my code I'm using
protected void ButtonSubmit_Click(object sender, EventArgs e)
{
JobDetail jobDetail = sched.GetJobDetail(hdnID.Value, hdnGroupID.Value);
jobDetail.JobDataMap["idname"] = txtName.Text;
jobDetail.JobDataMap["initialPath"] = TextBox1.Text;
jobDetail.JobDataMap["targetPath"] = TextBox2.Text;
jobDetail.JobDataMap["regex"] = TextBox3.Text;
jobDetail.JobDataMap["overrideemails"] = txtEmails.Text;
jobDetail.JobDataMap["flush"] = chkflush.Checked;
jobDetail.JobDataMap["impUsername"] = txtImpUsername.Text;
jobDetail.JobDataMap["impDomain"] = txtImpDomain.Text;
jobDetail.JobDataMap["impPassword"] = txtImpPassword.Text;
Trigger[] triggers = sched.GetTriggersOfJob(hdnID.Value, hdnGroupID.Value);
if (ddlScheduleType.SelectedIndex == 0)
{
foreach (SimpleTrigger trigger in triggers.OfType<SimpleTrigger>())
{
if (ddlInterval.SelectedIndex == 0)
{
trigger.RepeatInterval = TimeSpan.Parse("00:00:01");
}
else if (ddlInterval.SelectedIndex == 1)
{
trigger.RepeatInterval = TimeSpan.Parse("00:01:00");
}
else if (ddlInterval.SelectedIndex == 2)
{
trigger.RepeatInterval = TimeSpan.Parse("00:00:01");
}
}
}
else
{
foreach (CronTrigger trigger in triggers.OfType<CronTrigger>())
{
trigger.CronExpressionString = txtCron.Text;
}
}
}
(I know what I'm doing with the foreach loops is stupid, but there is only ever one trigger with a job and it's a snippet of code I recieved here).
Problem is, the page posts back fine and the new values still stay in the textboxes. But when I go view the job again, nothing changes at all. What am I doing wrong? It's confusing as there are no errors at all.
Note the hiddenfields are also correctly set.
Thanks
The ButtonSubmit_Click event is certainly working as I've debugged the program and the program goes through that.
The instance you get by calling sched.GetTriggersOfJob and sched.GetJobDetail are clones of the real triggers / jobs.
Your changes to those objects are not used by the scheduler until you reschedule the changed trigger or add a the changed job with the changed trigger.
I think you should be able to use RescheduleJob if you only change the triggers and you could remove the original trigger and add a new one.

Categories