I have 3 columns in the ListView. From,Subject,Date
I'm using the OpenPop library.
private int numberofallmessages = 0;
private int countMsg = 0;
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
OpenPop.Pop3.Pop3Client PopClient = new OpenPop.Pop3.Pop3Client();
PopClient.Connect("mail", 110, false);
PopClient.Authenticate("me", "me",
OpenPop.Pop3.AuthenticationMethod.UsernameAndPassword);
List<string> uids = PopClient.GetMessageUids();
int messageCount = PopClient.GetMessageCount() -1;
numberofallmessages = messageCount;
allMessages = new List<OpenPop.Mime.Message>(messageCount);
for (int i = messageCount; i > 0; i--)//for (int i = messageCount - 1; i > -1; i--)
{
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return;
}
string currentUidOnServer = uids[i];
if (!seenUids.Contains(currentUidOnServer))
{
if (i > 0)
allMessages.Add(PopClient.GetMessage(i));
SaveFullMessage(PopClient.GetMessage(i), i);
w = new StreamWriter(emailsIDSFile, true);
w.WriteLine(currentUidOnServer);
w.Close();
int nProgress = (messageCount - i + 1) * 100 / messageCount;
backgroundWorker1.ReportProgress(nProgress, PopClient.GetMessageCount().ToString() + "/" + i);
}
}
PopClient.Disconnect();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pbt.Value = e.ProgressPercentage;
pbt.Text = e.ProgressPercentage.ToString() + "%";
pbt.Invalidate();
label8.Text = e.UserState.ToString();
label8.Visible = true;
lvnf.Items.Add(new ListViewItem(new string[]
{
allMessages[countMsg].Headers.From.ToString(), //From Column
allMessages[countMsg].Headers.Subject, //Subject Column
allMessages[countMsg].Headers.DateSent.ToString() //Date Column
}));
countMsg += 1;
}
The problem is in the progresschanged event i think. Where i add the items to each column.
When it's adding the emails to the ListView i see it like this:
The problem is on the date column the date is fine but the time in not my time. Not sure of what place the time is but in my place it's now 1:52 AM
How can i get/set the time of my place ?
I couldn't find in the line:
allMessages[countMsg].Headers.DateSent.ToString()
How to change it to my time.
Try this:
allMessages[countMsg].Headers.DateSent.ToLocalTime().ToString();
You want to utilize the DateTime.ToLocalTime() method. It does the heavy lifting for you.
Hope this helps
Edit: Removed incorrect version as the documentation for OpenPop.Net states that the MessageHeader.DateSent property is in fact a DateTime object.
Related
I just need help on how to annotate a changed item in the list box if the user changes something using the text boxes provided.
namespace HW1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string[] values = new string[5];
values[0] = textBox1.Text;
values[1] = textBox2.Text;
values[2] = textBox3.Text;
values[3] = textBox4.Text;
values[4] = textBox5.Text;
string[] temp = new string[5];
temp[0] = textBox1.Text;
temp[1] = textBox2.Text;
temp[2] = textBox3.Text;
temp[3] = textBox4.Text;
temp[4] = textBox5.Text;
if(temp != values)
{
listBox1.SelectedIndex = 0 + "*";
listBox1.Text = values[1] + "*";
listBox1.Text = values[2] + "*";
listBox1.Text = values[3] + "*";
listBox1.Text = values[4] + "*";
}
listBox1.Items.Clear();
for (int i = 0; i < values.Length; i++)
{
listBox1.Items.Add(values[i].ToString());
}
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
The program will simply replace the old input from the text box with the new without displaying a * next to the item that has changed.
Your code doesn't actually compile... not sure how this line would ever work...
listBox1.SelectedIndex = 0 + "*";
Anyway - the main problem is that your for loop adds in values without the star to the list box
for (int i = 0; i < values.Length; i++)
{
listBox1.Items.Add(values[i].ToString()); //values[i] never has a star stored in it!
}
How about something like this...?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string[] values = new [] { textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text, textBox5.Text };
for (int i = 0; i < values.Length; i++)
{
if (listBox1.Items.Count < i + 1)
{
listBox1.Items.Add(values[i].ToString());
continue;
}
string unedited = listBox1.Items[i].ToString();
if (!string.IsNullOrEmpty(unedited) && unedited.Last() == '*')
unedited = listBox1.Items[i].ToString().Substring(0, listBox1.Items[i].ToString().Length - 1);
if (unedited != values[i])
listBox1.Items[i] = values[i] + "*";
else
listBox1.Items[i] = values[i];
}
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
This compares the list items to the textbox values.
If the textbox value doesn't exist, a listbox item is created.
If the listbox item doesn't match the textbox value, it has a * appended to it.
If an existing value (ignoring the star) is the same as the textbox value, it is updated to ensure the star is removed.
In this code I'm creating Few DataGridViews. Number of those depends on file which within each launch of application will be different, so is number of DataGridViews.
How can I Access particular dataGridView grid[i] and modify it from which event Form1_UserAddedRow was called in that method?
Code:
public void Form1_Load(object sender, EventArgs e)
{
string[] lines = System.IO.File.ReadAllLines(#"..\..\Base.txt");
int diet_num = 0;
int grid_num = 0;
foreach (string x in lines) diet_num++;
grid_num = (diet_num / Constant.DATAGRID_DIETS_IN_GRID) + 1;
DataGridView[] grid = new DataGridView[grid_num];
for (int i = 0; i < grid_num; i++)
{
grid[i] = new DataGridView();
grid[i].Tag = i;
grid[i].Parent = this;
grid[i].Location = new Point(12, 12 + (8 + Constant.DATAGRID_ROW_HEIGHT * 2) * i);
grid[i].Visible = true;
grid[i].RowHeadersVisible = false;
grid[i].Height = Constant.DATAGRID_ROW_HEIGHT * 2;
grid[i].Width = Constant.DATAGRID_COLUMN_SIZE * Constant.DATAGRID_DIETS_IN_GRID + 3;
grid[i].UserAddedRow += Form1_UserAddedRow;
}
this.Width = Constant.DATAGRID_COLUMN_SIZE * Constant.DATAGRID_DIETS_IN_GRID + 40;
foreach (string x in lines)
{
DataGridViewColumn col = new DataGridViewTextBoxColumn();
col.Width = Constant.DATAGRID_COLUMN_SIZE;
col.HeaderText = x;
int colIndex = grid[0].Columns.Add(col);
}
}
private void Form1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
//I want to access grid[i] and modify it here.
}
You should be able to cast the Sender object parameter in your event handler to the type of DataGridView to retrieve the grid which has been effected.
You are getting the DataGridViewRowEventArgs e as the argument to your event handler and thus you can access the Row property like
e.Row.Cells["somename"].Value = "some_value";
private void Form1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
var grid = sender as DataGridView;
if (grid == null) return;
//... do something
}
I have three combobx for time and I want to edit the text of this comboboxes from another view this is the code for combobpx view
public partial class Combo : Window
{
public Combo()
{
InitializeComponent();
}
private void hrComboBox_Loaded(object sender, RoutedEventArgs e)
{
List<string> hours = new List<string>();
for (int i = 0; i <= 24; i++)
{
if (i < 10)
hours.Add("0" + i);
else
hours.Add(i + "");
}
var comboBox = sender as ComboBox;
comboBox.ItemsSource = hours;
comboBox.SelectedIndex = 0;
}
private void MinComboBox_Loaded(object sender, RoutedEventArgs e)
{
List<string> Minutes = new List<string>();
for (int i = 0; i <= 60; i++)
{
if (i < 10)
Minutes.Add("0" + i);
else
Minutes.Add(i + "");
}
var comboBox = sender as ComboBox;
comboBox.ItemsSource = Minutes;
comboBox.SelectedIndex = 0;
}
private void SecComboBox_Loaded(object sender, RoutedEventArgs e)
{
List<string> Seconds = new List<string>();
for (int i = 0; i <= 60; i++)
{
if (i < 10)
Seconds.Add("0" + i);
else
Seconds.Add(i + "");
}
var comboBox = sender as ComboBox;
comboBox.ItemsSource = Seconds;
comboBox.SelectedIndex = 0;
}
private void OKButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
DialogResult = true;
}
the second view invokes this view as dialog my problem is when I add the text to one of this comboboxes the text isn't set and still "00" the code I use as follows:
var dialog = new Combo();
string[] timeArr = delay.Split(':');
//here is my problem when the dialog is loading the text
//of three comboboxes isn't change
dialog.hr.Text = timeArr[0];
dialog.Min.Text = timeArr[1];
dialog.Sec.Text = timeArr[2];
if (dialog.ShowDialog() == true)
{
string time = dialog.hr.Text+":"+dialog.Min.Text+":"+dialog.Sec.Text;
delay = time;
nextDelay = time;
}
anyone help me, thanks :)
private int numberofallmessages = 0;
private int countMsg = 0;
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
OpenPop.Pop3.Pop3Client PopClient = new OpenPop.Pop3.Pop3Client();
PopClient.Connect("mail", 110, false);
PopClient.Authenticate("me", "me",
OpenPop.Pop3.AuthenticationMethod.UsernameAndPassword);
int messageCount = PopClient.GetMessageCount();
numberofallmessages = messageCount;
allMessages = new List<OpenPop.Mime.Message>(messageCount);
for (int i = messageCount; i > 0; i--)
{
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return;
}
allMessages.Add(PopClient.GetMessage(i));
int nProgress = (messageCount - i + 1) * 100 / messageCount;
backgroundWorker1.ReportProgress(nProgress, PopClient.GetMessageCount().ToString() + "/" + i);
}
PopClient.Disconnect();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pbt.Value = e.ProgressPercentage;
pbt.Text = e.ProgressPercentage.ToString() + "%";
pbt.Invalidate();
label8.Text = e.UserState.ToString();
label8.Visible = true;
lstMail.Items.Add(allMessages[countMsg].Headers.Subject + " " + allMessages[countMsg].Headers.DateSent);
countMsg += 1;
}
In the ProgressChanged event i'm adding the items to the listView(lstMail).
lstMail.Items.Add(allMessages[countMsg].Headers.Subject + " " + allMessages[countMsg].Headers.DateSent);
But this line will keep adding also the DateSent to the first tab and not to the date tab:
There is a subject tab and a date tab and i want that the part
allMessages[countMsg].Headers.DateSent
Will be under the date tab.
Change this line:
lstMail.Items.Add(allMessages[countMsg].Headers.Subject + " " + allMessages[countMsg].Headers.DateSent);
To:
lstMail.Items.Add(new ListViewItem(new string[]
{
"", //From Column
allMessages[countMsg].Headers.Subject, //Subject Column
allMessages[countMsg].Headers.DateSent.ToString() //Date Column
}));
Hope this helps.
This is the standard way of adding items to columns in a listView.
ListViewItem item1 = new ListViewItem("Something");
item1.SubItems.Add("SubItem1a");
item1.SubItems.Add("SubItem1b");
item1.SubItems.Add("SubItem1c");
ListViewItem item2 = new ListViewItem("Something2");
item2.SubItems.Add("SubItem2a");
item2.SubItems.Add("SubItem2b");
item2.SubItems.Add("SubItem2c");
ListViewItem item3 = new ListViewItem("Something3");
item3.SubItems.Add("SubItem3a");
item3.SubItems.Add("SubItem3b");
item3.SubItems.Add("SubItem3c");
ListView1.Items.AddRange(new ListViewItem[] {item1,item2,item3});
Also see:
C# listView, how do I add items to columns 2, 3 and 4 etc?
Okay, I have a loading animation that runs while a large DataTable is populated to let the user know that the program has not frozen. I have the animation working fine, but it freezes while the DataTable is updatingv as well. Is there some way to have multiple UI threads, so that the animation will continue to run while the DataTable is loading information?
EDIT: Current code is below.
private void CreateFileTable()
{
file_data = new DataSet();
data_table = new DataTable();
file_data.Tables.Add(data_table);
DataColumn tempCol = new DataColumn("File Name", typeof(string));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Ext", typeof(string));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Size", typeof(string));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Created", typeof(Label));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Modified", typeof(Label));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Accessed", typeof(Label));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Location", typeof(string));
data_table.Columns.Add(tempCol);
File_List.ItemsSource = file_data.Tables[0].DefaultView;
}
private void PopulateDirectories(string[] directories)
{
for (int i = 0; i < directories.Length; i++)
{
DirectoryInfo tempDirInfo = new DirectoryInfo(directories[i]);
bool isSystem = ((tempDirInfo.Attributes & FileAttributes.System) == FileAttributes.System);
if (!isSystem)
{
DataRow tempRow = data_table.NewRow();
tempRow["File Name"] = tempDirInfo.Name;
tempRow["Ext"] = "";
tempRow["Size"] = "";
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempDirInfo.CreationTime.ToLongDateString() + ", " + tempDirInfo.CreationTime.ToLongTimeString();
tempRow["Created"] = tempLabel;
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempDirInfo.LastWriteTime.ToLongDateString() + ", " + tempDirInfo.LastWriteTime.ToLongTimeString();
tempRow["Modified"] = tempLabel;
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempDirInfo.LastAccessTime.ToLongDateString() + ", " + tempDirInfo.LastAccessTime.ToLongTimeString();
tempRow["Accessed"] = tempLabel;
tempRow["Location"] = tempDirInfo.FullName;
data_table.Rows.Add(tempRow);
}
}
}
private void PopulateFiles(string[] files)
{
for (int i = 0; i < files.Length; i++)
{
FileInfo tempFileInfo = new FileInfo(files[i]);
bool isSystem = ((File.GetAttributes(files[i]) & FileAttributes.System) == FileAttributes.System);
if (!isSystem)
{
DataRow tempRow = data_table.NewRow();
tempRow["File Name"] = tempFileInfo.Name;
tempRow["Ext"] = tempFileInfo.Extension;
int fileSize = (int)tempFileInfo.Length;
if (fileSize > 1048576)
{
tempRow["Size"] = "" + fileSize / 1048576 + " MB";
}
else if (fileSize > 1024)
{
tempRow["Size"] = "" + fileSize / 1024 + " KB";
}
else
{
tempRow["Size"] = "" + fileSize + " B";
}
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempFileInfo.CreationTime.ToLongDateString() + ", " + tempFileInfo.CreationTime.ToLongTimeString();
tempRow["Created"] = tempLabel;
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempFileInfo.LastWriteTime.ToLongDateString() + ", " + tempFileInfo.LastWriteTime.ToLongTimeString();
tempRow["Modified"] = tempLabel;
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempFileInfo.LastAccessTime.ToLongDateString() + ", " + tempFileInfo.LastAccessTime.ToLongTimeString();
tempRow["Accessed"] = tempLabel;
tempRow["Location"] = tempFileInfo.DirectoryName;
data_table.Rows.Add(tempRow);
}
}
}
private string GetSelectedPath(TreeViewItem selectedNode)
{
return selectedNode.Tag as string;
}
private void PopulateFileList()
{
PopulateDirectories(Directory.GetDirectories(GetSelectedPath((TreeViewItem)Dir_Tree.SelectedItem)));
PopulateFiles(Directory.GetFiles(GetSelectedPath((TreeViewItem)Dir_Tree.SelectedItem)));
}
private void UpdateFileList()
{
LoadingWheel.Visibility = System.Windows.Visibility.Visible;
CreateFileTable();
PopulateFileList();
TxtFoundCount.Text = "Files/Folders Found: " + File_List.Items.Count;
LoadingWheel.Visibility = System.Windows.Visibility.Hidden;
}
I have tried using the BackgroundWorker and calling the UpdateFileList() method inside it, but I'm not having any luck.
EDIT: Below is my code for the BackgroundWorker.
private BackgroundWorker bgWorker1;
private void InitializeBackgroundWorker()
{
bgWorker1 = new BackgroundWorker();
bgWorker1.DoWork += new DoWorkEventHandler(bgWorker1_DoWork);
bgWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker1_RunWorkerCompleted);
}
private void bgWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (Dispatcher.CheckAccess())
{
PopulateFileList();
}
else
{
Dispatcher.Invoke(new Action(() => PopulateFileList()));
}
}
private void bgWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
TxtFoundCount.Text = "Files/Folders Found: " + File_List.Items.Count;
LoadingWheel.Visibility = System.Windows.Visibility.Hidden;
}
private void UpdateFileList()
{
LoadingWheel.Visibility = System.Windows.Visibility.Visible;
CreateFileTable();
bgWorker1.RunWorkerAsync();
}
I have a SelectionChanged event on a TreeView that calls InitializeBackgroundWorker() and UpdateFileList(). The list loads still, and I get no errors, but the loading animation never becomes visible.
Any help would be greatly appreciated.
Thanks.
There is only one UI thread. What you need to do is to load the data in the DataTable on a different thread.
If you want to show progress to the DataTable loading along the way (either directly, or through a ProgressBar or some other mechanism), the BackgroundWorker is a fairly straight-forward way to do that.
UPDATE: Very Simple Background Worker example
Here is a fairly simple example. It adds 100 random numbers to a collection, pausing the thread for a short time between each to simulate a long loading process. You can simply cut and paste this into a test project of your own to see it work.
The thing to notice is that the heavy lifting (the stuff that takes a while) is done in the DoWork, while all UI updates are done in ProgressChanged and RunWorkerCompleted. In fact, a separate list (numbers) is created in the DoWork handler because the global mNumbers collection is on the UI thread, and can't interact in the DoWork handler.
XAML
<Button x:Name="btnGenerateNumbers"
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Generate Numbers" />
C# Code-Behind
BackgroundWorker bgWorker = new BackgroundWorker();
ObservableCollection<int> mNumbers = new ObservableCollection<int>();
public Window1()
{
InitializeComponent();
bgWorker.DoWork +=
new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.ProgressChanged +=
new ProgressChangedEventHandler(bgWorker_ProgressChanged);
bgWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
bgWorker.WorkerReportsProgress = true;
btnGenerateNumbers.Click += (s, e) => UpdateNumbers();
this.DataContext = this;
}
void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progress.Visibility = Visibility.Collapsed;
lstItems.Opacity = 1d;
btnGenerateNumbers.IsEnabled = true;
}
void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
List<int> numbers = (List<int>)e.UserState;
foreach (int number in numbers)
{
mNumbers.Add(number);
}
progress.Value = e.ProgressPercentage;
}
void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
Random rnd = new Random();
List<int> numbers = new List<int>(10);
for (int i = 1; i <= 100; i++)
{
// Add a random number
numbers.Add(rnd.Next());
// Sleep from 1/8 of a second to 1 second
Thread.Sleep(rnd.Next(125, 1000));
// Every 10 iterations, report progress
if ((i % 10) == 0)
{
bgWorker.ReportProgress(i, numbers.ToList<int>());
numbers.Clear();
}
}
}
public ObservableCollection<int> NumberItems
{
get { return mNumbers; }
}
private void UpdateNumbers()
{
btnGenerateNumbers.IsEnabled = false;
mNumbers.Clear();
progress.Value = 0;
progress.Visibility = Visibility.Visible;
lstItems.Opacity = 0.5;
bgWorker.RunWorkerAsync();
}
I wrote a little test program which shows the use of the Dispatcher class. It just requires a WPF-Window and a ListBox with Name "listBox". Should be easy to apply this solution to your problem.
public void Populate() {
// for comparison, freezing the ui thread
for (int i = 0; i < 1000000; i++) {
listBox.Items.Add(i);
}
}
private delegate void AddItemDelegate(int item);
public void PopulateAsync() {
// create a new thread which is iterating the elements
new System.Threading.Thread(new System.Threading.ThreadStart(delegate() {
// inside the new thread: iterate the elements
for (int i = 0; i < 1000000; i++) {
// use the dispatcher to "queue" the insertion of elements into the UI-Thread
// DispatcherPriority.Background ensures Animations have a higher Priority and the UI does not freeze
// possible enhancement: group the "jobs" to small units to enhance the performance
listBox.Dispatcher.Invoke(new AddItemDelegate(delegate(int item) {
listBox.Items.Add(item);
}), System.Windows.Threading.DispatcherPriority.Background, i);
}
})).Start();
}