How can I delete every item in my list? - c#

How do I remove everything on my listview with my clickfunction below?
Now it only removes the first item in the list and not every item.
This is my code:
async void OnButtonClickedRemoveEverything (object sender, EventArgs args)
{
theGuestListMembers ourItem = null; //theGuestListMembers is our Class.
foreach (theGuestListMembers c in ourEventList) { //oureventlist = this is Our List.
ourItem = c;
}
// . listID is a public string that gets the personal "info" from a user (the objectID). so I guess the "ourItem.listID" is our problem because I only get 1 persons objectID i guess not everyone from the list?
if(ourItem != null)
{
parseAPI.deleteTheGuestList
(Application.Current.Properties ["sessionToken"].ToString (), ourItem.listID);
ourEventList.Remove (ourItem);
EmployeeList.ItemsSource = null; //name of our list
EmployeeList.ItemsSource = ourEventList;
}
Navigation.PopAsync ();
}
My database where i get info.
var getItems = await parseAPI.getOurGuestList (Application.Current.Properties ["sessionToken"].ToString (), owner);
EmployeeList.ItemsSource = null;
ourEventList = new List<theGuestListMembers> ();
foreach (var currentItem in getItems["results"]) {
ourEventList.Add (new theGuestListMembers () {
listID = currentItem ["objectId"].ToString (),
theHeadName = currentItem ["YourName"].ToString ()
});
}

If you simply want to remove the items from the list, you can use ourEventList.Clear() or ourEventList.RemoveAll(ourItem => ourItem != null)
If you want to do something fancier, you can use this function:
private bool removeItem(theGuestListMember ourItem)
{
if (ourItem == null) return false;
parseAPI.deleteTheGuestList(ourItem);
return true;
}
And use it like this:
async private void OnButtonClickedRemoveEverything(object sender, EventArgs e)
{
ourEventList.RemoveAll(ourItem => removeItem(ourItem);
EmployeeList.ItemsSource = ourEventList;
Navigation.PopAsync ();
}

Related

How to search file and display it in list box?

I am stuck with the project C# and I don't know how to solve it. I have a text file "cars.txt" and it has this information:
1950
Nissan Sentra
Ford Focus
1951
Mazda5
Mazda3
Toyota
1952
Chevy
I have to have 2 list boxes and one button. The first list box supposed to search through the file and populate years and when user select year and click on the button and it displays the corresponding cars models for this specific year. I have thoughts about using StreamReader but I don't know how to start.
Your help appreciated
Create a dictionary of string lists that will contain car lists with the year a key as well as a list for the years:
private readonly Dictionary<int, List<string>> _carsByYear =
new Dictionary<int, List<string>>();
private readonly List<int> _years = new List<int>();
Then you can fill it with
List<string> cars = null;
foreach (string line in File.ReadLines(#"C:\Users\Me\cars.txt")) {
if (!String.IsNullOrWhiteSpace(line)) {
if (Int32.TryParse(line, out int year)) { // We have a year
if (_carsByYear.TryGetValue(year, out var existingList)) {
cars = existingList;
} else {
// Add a new list with year as the key
_years.Add(year);
cars = new List<string>();
_carsByYear.Add(year, cars);
}
} else { // We have a car
cars.Add(line);
}
}
}
Now you can assign _years to the DataSource of the first ListBox. You can get the selected year (SelectedIndexChanged event) with
int year = (int)listBox1.SelectedItem;
With this year, you can get the cars list with
var selectedCarList = _carsByYear[year];
Assign it to the DataSource of the second ListBox.
now the is no error but nothing displayed. This is a very challenging
assignment. everyone in my class is stuck.
Works fine for me. Here's a variation with some examples of how you could use it:
private readonly SortedList<int, SortedSet<string>> _carsByYear = new SortedList<int, SortedSet<string>>();
private void button1_Click(object sender, EventArgs e)
{
SortedSet<string> cars = null;
string fileName = System.IO.Path.Combine(
System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"cars.txt");
foreach (string line in File.ReadLines(fileName))
{
if (!String.IsNullOrWhiteSpace(line))
{
if (Int32.TryParse(line, out int year))
{ // We have a year
if (!_carsByYear.ContainsKey(year))
{
cars = new SortedSet<string>();
_carsByYear.Add(year, cars);
}
else
{
cars = _carsByYear[year];
}
}
else
{ // We have a car
if (!cars.Contains(line))
{
cars.Add(line);
}
}
}
}
listBox1.DataSource = _carsByYear.Keys.ToList();
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedIndex != -1)
{
listBox2.DataSource = _carsByYear[(int)listBox1.SelectedItem].ToList();
}
}
private void button2_Click(object sender, EventArgs e)
{
if (listBox1.SelectedIndex != -1 && listBox2.SelectedIndex != -1)
{
int year = (int)listBox1.SelectedItem;
string car = listBox2.SelectedItem.ToString();
label1.Text = year.ToString();
label2.Text = car;
}
else
{
label1.Text = "";
label2.Text = "";
}
}
If you still can't get it to work, give MORE DETAILS about the contents of the file and how you're supposed to use it in your interface.

How to stop Custom OnSaving event after first saving in SItecore?

I am trying to stop my custom OnSaving event after it has been applied to the first item in the save chain.
but so far I have not been able to, and I end up with a stackoverflow exception.
Is there a simple way of doing this ?
Best regards,
Robin
private void AddOrRemoveRedirectingItemIdFromSavingItemIdList(Item savingItem, SitecoreEventArgs sitecoreEventArgs)
{
ItemLink[] referers = Globals.LinkDatabase.GetReferrers(savingItem);
var guidList = new List<ID>();
foreach (ItemLink link in referers)
{
// checking the database name of the linked Item
if (!link.SourceDatabaseName.Equals(Context.ContentDatabase.Name, StringComparison.CurrentCultureIgnoreCase))
{
continue;
}
Item item = Context.ContentDatabase.Items[link.SourceItemID, savingItem.Language];
// adding the Item to an array if the Item is not null
if (item == null || item.Fields["301Redirect"] == null || item.Fields["301RedirectedTo"] == null)
{
continue;
}
// Update the saving item ids
CheckboxField redirectField = item.Fields["301Redirect"];
if (redirectField.Checked)
{
guidList.Add(item.ID);
}
}
if (guidList.Any())
{
this.SaveIDsToEditingItem(savingItem, guidList, false);
}
}
private void SaveIDsToEditingItem(Item editingItem, IEnumerable<ID> guidList, bool forceModified)
{
Field redirectedToFromItemId = editingItem.Fields["301RedirectedToFromItemId"];
using (new EditContext(editingItem))
{
// Saving the redirected items ids
string redirectedToFromItemIdOld = redirectedToFromItemId.Value;
string redirectedToFromItemIdNew = string.Join("\n", guidList.Select(guid => guid.ToString()));
// if the values are not changed
if (redirectedToFromItemIdNew.Equals(redirectedToFromItemIdOld))
{
return;
}
redirectedToFromItemId.Value = redirectedToFromItemIdNew;
if (forceModified)
{
editingItem.RuntimeSettings.ForceModified = true;
}
}
}
}
You can do this 2 ways. The better way would be to remove the using (new EditingContext(editingItem) section from the SaveIDsToEditingItem. In the OnItemSaving event, any changes made to the savingItem would be kept.
Alternatively, if you need to use the editing context for some reason you need to use an EventDisabler in your SaveIDsToEditingItem method:
private void SaveIDsToEditingItem(Item editingItem, IEnumerable<ID> guidList, bool forceModified)
{
Field redirectedToFromItemId = editingItem.Fields["301RedirectedToFromItemId"];
using (new EventDisabler())
{
using (new EditContext(editingItem))
{
// Saving the redirected items ids
string redirectedToFromItemIdOld = redirectedToFromItemId.Value;
string redirectedToFromItemIdNew = string.Join("\n", guidList.Select(guid => guid.ToString()));
// if the values are not changed
if (redirectedToFromItemIdNew.Equals(redirectedToFromItemIdOld))
{
return;
}
redirectedToFromItemId.Value = redirectedToFromItemIdNew;
if (forceModified)
{
editingItem.RuntimeSettings.ForceModified = true;
}
}
}
}
This will prevent the OnSaving event from being fired again.

MoveNext for List

I'm trying to create an application where you press the next button and it shows the next object in a list. In this case an object of Employee, I'm using Linq To SQL. I've read about MoveNext, but I don't know how it works and I tried something else which doesn't work (code below). Basically I want to have a next/previous button to get employees from the db.
Here's the code to get all Employees:
public List<Employee> GetEmployees()
{
var q =
from a in db.GetTable<Employee>()
select a;
List<Employee> employeeList = q.ToList();
return employeeList;
}
Button click:
private void btnNext_Click(object sender, EventArgs e)
{
Increment();
LoadEmployee();
}
Increment (method) (this is my solution for getting the next object, but it isn't optimal at all):
public void Increment()
{
if (con.GetEmployee(id) != null)
{
id++;
}
else
{
id += 2;
}
}
LoadEmployee (method):
public void LoadEmployee()
{
Employee e = con.GetEmployees().FirstOrDefault(f => f.id.Equals(id));
tbId.Text = e.id.ToString();
tbFname.Text = e.Fname;
tbLname.Text = e.Lname;
tbDate.Text = e.Date;
}
Sir, try this
public void LoadEmployee()
{
Employee e = con.GetEmployees();
tbId.Text = e[id].id.ToString();
tbFname.Text = e[id].Fname;
tbLname.Text = e[id].Lname;
tbDate.Text = e[id].Date;
}
use id as an index of your collection
So to summarise:
You're using SQL
And want to take a record with 'next' / 'prev'.
If you look at SQL itself without using cursors, I'd say that translates as a 'skip' and 'take 1'. Linq has these features:
// initialize index
int x = -1;
// move next:
var currentEmployee = context.Employees.Skip(++x).FirstOrDefault();
if (currentEmployee == null)
{
// End.
}
// move prev:
if (--x < 0)
{
// move back past start
x = 0;
}
var currentEmployee = context.Employees.Skip(x).FirstOrDefault();
if (currentEmployee == null)
{
// No elements
}

TextBox LostFocus infinite loop

I have a textbox in my form for user to key in an item code.
When the focus of the textbox is lost, it will look into the database to check if the item code exists or not.
However, I am getting infinite loop when I try to lose focus by clicking on other textboxes.
private void txtICode_LostFocus(object sender, RoutedEventArgs e)
{
if (txtICode.IsFocused != true)
{
if (NewData)
{
if (txtICode.Text != null)
{
if (txtICode.Text != "")
{
Item temp = new Item();
Item[] list = temp.Query(new object[] { Item.DataEnum.Item_Code }, new string[] { txtICode.Text });
if (list.Length > 0)
{
System.Windows.Forms.MessageBox.Show("This item code is already being used.", "Invalid information");
txtICode.Focus();
return;
}
}
}
}
}
}
The txtICode.IsFocused is set to true every time after the end of the method and the loop just continues forever.
I tried removing txtICode.Focus(); but it makes no difference.
Is there anything wrong with my code?
I am using .Net 3.5 and WPF for my form.
You do not have to restore focus to TextBox in the LostFocus event.
remove these 2 lines :
txtICode.Focus();
return;
You could implement code more clean & readable way :
private void txtICode_LostFocus(object sender, RoutedEventArgs e)
{
if (!NewData)
return;
if (String.IsNullOrEmpty(txtICode.Text))
return;
Item temp = new Item();
Item[] list = temp.Query(new object[] { Item.DataEnum.Item_Code }, new string[] { txtICode.Text });
if (list.Length > 0)
{
System.Windows.Forms.MessageBox.Show("This item code is already being used.", "Invalid information");
}
}
private void txtICode_LostFocus(object sender, RoutedEventArgs e)
{
string inputText = txtICode.Text;
if (string.IsNullOrEmpty(inputText) || !NewData)
{
return;
}
Item temp = new Item();
Item[] list = temp.Query(new object[] { Item.DataEnum.Item_Code },
new string[] { inputText });
if (list != null && list.Length > 0)
{
MessageBox.Show("This item code is already being used.", "Invalidinformation");
txtICode.Focus();
return;
}
}
You can use BeginInvoke Method to execute asynchronously:
private void txtICode_LostFocus(object sender, RoutedEventArgs e)
{
txtICode.Dispatcher.BeginInvoke(() => {
if (txtICode.IsFocused != true)
{
if (NewData)
{
if (txtICode.Text != null)
{
if (txtICode.Text != "")
{
Item temp = new Item();
Item[] list = temp.Query(new object[] { Item.DataEnum.Item_Code }, new string[] { txtICode.Text });
if (list.Length > 0)
{
System.Windows.Forms.MessageBox.Show("This item code is already being used.", "Invalid information");
txtICode.Focus();
return;
}
}
}
}
});
}

Sorting a ListBox of objects by attributes

I have a list created by:
List<Song> SongList = new List<Song>();
Populated by a bunch of:
SongList.Add(new Song(songID, "Dirt", "Alice in Chains", "Rooster", "Rock", "02:32"));
The details of songs are populated into a ListBox by:
private void songTitle_TextChanged(object sender, EventArgs e)
{
i = 0;
for (; i < songTitle.Text.Length; i++)
{
songResultBox.Items.Clear();
var songResult = from song in SongList
where song.SongTitle != null && song.SongTitle.Length >= songTitle.Text.Length
&& songTitle.Text == song.SongTitle.Substring(0, i+1)
select new { sId = song.SongID, album = song.SongAlbum, artist = song.SongArtist, title = song.SongTitle,
genre = song.SongGenre, length = song.SongLength };
foreach (var item in songResult)
{
songResultBox.Items.Add(new Song(item.sId, item.album, item.artist, item.title, item.genre, item.length));
songResultBox.DisplayMember = "FullName";
songResultBox.ValueMember = "songID";
}
}
}
Question is: How would I create a button (or 4 in fact) that took the contents of the ListBox 'songResultBox' and sorted its contents by title, album, artist, genre etc.
Create the button, label it depending on what property you want to sort on, add a click event to the button, sort the items (hopefully you've maintained a list of them), then repopulate the listbox:
private bool descendingSongTitleSort = false;
private bool descendingArtistSort = false;
// Artist button clicked event
private void artistButtonClicked(object sender, EventArgs args)
{
Func<Song, IComparable> sortProp = (song => song.Artist);
sortListBox(songResultBox, descendingArtistSort, sortProp);
descendingSongTitleSort = false;
descendingArtistSort = !descendingArtistSort;
}
// Title button clicked event
private void titleButtonClicked(object sender, EventArgs args)
{
Func<Song, IComparable> sortProp = (song => song.Title);
sortListBox(songResultBox, descendingSongTitleSort, sortProp);
descendingSongTitleSort = !descendingSongTitleSort;
descendingArtistSort = false;
}
// Sorting function
private void sortListBox(
ListBox box,
bool descending,
Func<Song, IComparable> sortProperty)
{
List<Song> items = new List<Song>();
foreach (Object o in box.Items)
{
Song s = o as Song;
items.Add(s);
}
box.Items.Clear();
if(descending)
{
items = items.OrderByDescending(sortProperty).ToList();
}
else
{
items = items.OrderBy(sortProperty).ToList();
}
foreach(Song s in items)
{
box.Items.Add(s);
}
}
The descending bools aren't necessary if you don't want to worry about resorting in the opposite direction.

Categories