I'm having weird behavior with my messagebox
here is the code:
private async void rate_Tap(object sender, System.Windows.Input.GestureEventArgs e) {
string id = (string)((Image)sender).Tag;
ignoreSelectionChanged = true;
MobileServiceCollection<rating, rating> items;
IMobileServiceTable<rating> itemTable = App.MobileService.GetTable<rating>();
items = await itemTable
.Where(Table => Table.userid == userId)
.ToCollectionAsync();
if (id != null) {
for (int i = 0; i < items.Count; i++) {
if (items[i].itemid == id) {
MessageBox.Show("You already giving your rating.");
i = items.Count;
return;
}
else {
RadMessageBox.Show(
new string[] { "very accurate", "not accurate" },
"Acurate?",
"Is this information accurate?", closedHandler: (args) => {
int buttonIndex = args.ButtonIndex;
if (buttonIndex == 0) {
clearListBox();
ratingPlus(id);
saveRating(id);
mvm.LoadDetailData();
}
if (buttonIndex == 1) {
clearListBox();
ratingMinus(id);
saveRating(id);
mvm.LoadDetailData();
}
}
);
}
}
}
}
What my code above dord is I trigger rate_Tap() from my listbox that already contains image, and each time I tap it , it's supposed to check with my windows azure server and check if there is an itemid that equals id. Then I will show messagebox saying I already rated it and if there isn't any itemid that equals id then it will execute radmessagebox.
But it's not working that way: when it checks there is an itemid that's equal to id, it shows the messagebox and after that it show the radmessagebox.
Where did I go wrong?
Your "else" block contains the code that you want to execute after you've checked all items - not on each item.
I think you want:
if (items.Any(item => item.itemid == id))
{
MessageBox.Show("You already giving your rating.");
return;
}
RadMessageBox.Show(...);
// etc
Ideally, don't fetch all the previous ratings - change your query so that it includes the ID of the item you're trying to rate. After all, you only want to know whether or not you've already rated it - the rest of the information is pointless, so why fetch it all?
Related
I realize this may look like a duplicate question (I've seen many other questions asking about this error), however I cannot find an answer which explains the issue I'm having. The error is provoked by a call to
invList.SelectedItems[0].Text //invList is a ListView
From what I've read, the error when provoked by this instruction is indicative of attempted access to an empty list (or array?) of selected items in the ListView. However, the ListView I am attempting to access is populated with items at the time of the instruction's execution. Here are the methods in which I issue this instruction:
Method #1: deleteItem
public bool deleteItem()
{
if (invList.SelectedItems.Count == 0) //if no item selected...
{
MessageBox.Show("Error: No item selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
else
{
DialogResult dialogResult = MessageBox.Show(
"Are you sure you want to delete item: " + invList.SelectedItems[0].Text + "?",
"Error", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dialogResult == DialogResult.Yes)
{
for (int i = 0; i < itemRecords.Count; i++)
{
if ((itemRecords[i].id.ToString() == invList.SelectedItems[0].Text) && (itemRecords[i].practice == clinicName))
{
itemRecords.Remove(itemRecords[i]);
listRefresh();
}
}
return true; //return true to indicate that data has been edited
}
return false; // return false to indicate that nothing has changed
}
}
Method #2: updateItem
public bool updateItem()
{
if (invList.SelectedItems.Count == 0) //if no item selected
{
MessageBox.Show("Error: No item selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
else
{
for (int i = 0; i < itemRecords.Count; i++)
{
//if id == the id of the selected item
if((itemRecords[i].id.ToString() == invList.SelectedItems[0].Text) && (itemRecords[i].practice == this.Text))
{
ItemAddition itemAddition = new ItemAddition(itemRecords, itemRecords[i], this);
itemAddition.ShowDialog();
}
}
return true;
}
}
listRefresh:
public void listRefresh()
{
invList.Items.Clear();
loadItems();
}
loadItems:
private void loadItems()
{
foreach (Record r in itemRecords)
{
if (r.practice == clinicName)
invList.Items.Add(r.ToString());
}
}
The error is invoked when the first method is called, but NOT when the second method is called. This inconsistency is the reason for my confusion. Is there some reason this error would only occur in the first method?
Move refreshing method after remove items. If you move item and rebind, then you will lost selection.
for (int i = 0; i < itemRecords.Count; i++)
{
if ((itemRecords[i].id.ToString() == invList.SelectedItems[0].Text) && (itemRecords[i].practice == clinicName))
{
itemRecords.Remove(itemRecords[i]);
//listRefresh();
}
}
listRefresh();
return true;
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
}
I made a code that check if in my DataGrid a particular element is already exists.
If the elements is already added in the DataGrid the code show a pop-up to the user. This is the code:
if (grid.Items.Count > 0)
{
for (int i = 0; i < grid.Items.Count; i++)
{
if (((Teams.Club_Information)grid.Items[i]).name == reader["name"].ToString())
{
MessageBox.Show("La squadra è già stata inserita!");
}
else
{
MainWindow.AppWindow.Squadre_DataGrid.Items.Add(new Teams.Club_Information
{
name = reader["name"].ToString(),
code = reader["code"].ToString(),
shortName = reader["shortName"].ToString(),
squadMarketValue = reader["SquadMarketValue"].ToString()
});
}
}
}
else
{
MainWindow.AppWindow.Squadre_DataGrid.Items.Add(new Teams.Club_Information
{
name = reader["name"].ToString(),
code = reader["code"].ToString(),
shortName = reader["shortName"].ToString(),
squadMarketValue = reader["SquadMarketValue"].ToString()
});
}
In the first condition I check if there's row in the DataGrid, if the condition is true then I iterate through the element of DataGrid.
Now the problem is that I'm compare a grid item with the attribute "name" of the reader. reader is the variable the read of the element of a query result (sqlite).
There's another way to check in the column name of my DataGrid if the element is already added?
Your items are of type "Teams.Club_Information", but you are comparing them to reader["name"] which is a string. Unless you have written an Equals method which will compare Club_Information.name to a string, the comparison will always fail.
Try instead:
if (((Teams.Club_Information)grid.Items[i]).name == reader["name"])
You can do something like this
if(grid.Items.Contains(reader["name"]))
{
MessageBox.Show("team already added");
}
else
{
MainWindow.AppWindow.Squadre_DataGrid.Items.Add(new Teams.Club_Information
{
name = reader["name"].ToString(),
code = reader["code"].ToString(),
shortName = reader["shortName"].ToString(),
squadMarketValue = reader["SquadMarketValue"].ToString()
});
}
var name = reader["name"];
var isNamePresent = grid.Items
.Cast<Teams.Club_Information>()
.Any(item => item.name == name);
if (isNamePresent) ... else ...
I wanna check a value in array and if it exist return the value else return the message and read another value from array. add
else
{
MessageBox.Show("This Item ID Does Not Exist");
}
but the problem is when the the value is not in array, it want to show the message for 1258038 times.
how can I check the value (input) and if it exists, i can continue and if it does not exist in array , it returns back and read another value (input can be several values that must read one by one)
for (int cun = 0; cun < ItemIdNumber.Length; cun++)
{
int Item_Id = Convert.ToInt32(ItemIdNumber[cun]);
for (int yyu = 0; yyu <= 1258038; yyu++)
{
int weer = c[yyu];
if (weer == Item_Id)
{
itemseq = yyu;
}
else
{
MessageBox.Show("This Item ID Does Not Exist");
}
}
float[] i_ff = b[itemseq];
for (int ii = 0; ii < i_ff.Length; ii++)
{
.......
Use break to leave the loop early. You'll also need to change your logic a bit so you're not displaying a message in every iteration. This is just one possibility:
int? itemseq = null;
for (...) // outer loop
{
...
for (...) // inner loop
{
if (weer == Item_Id)
{
itemseq = yyu;
break;
}
}
if (!itemseq.HasValue)
MessageBox.Show("This Item ID Does Not Exist");
...
}
I think with a little bit of thought, you could make this more readable.
You've got two collections to search - ItemIdNumber and c.
You're looking for the first value in ItemIdNumber that matches an item in the first 1258038 values of c.
Something like this LINQ statement maybe, although I'm not exactly sure what type your collections are. And I'm writing this free-hand, so it might not compile as-is. Should give you something to work with though.
var id = (from id in ItemIdNumber
join cid in c.Take(1258038) on Convert.ToInt32(id) equals cid
select cid).FirstOrDefault();
if (!id.HasValue)
MessageBox.Show("This Item ID Does Not Exist");
for (int cun = 0; cun < ItemIdNumber.Length; cun++) {
...
boolean found = false;
for (int yyu = 0; yyu <= 1258038; yyu++) {
int weer = c[yyu];
if (weer == Item_Id)
{
itemseq = yyu;
found = true;
break;
}
}
if(!found) {
MessageBox.Show("This Item ID Does Not Exist");
}
...
}
So I have a this model http://i.imgur.com/tz8ZVPT.png , and I would like create a Update with a Program, so I first create the update, fill in all the neccesary items, find a MachineType and maybe a program, but if none is found, get the first program from the MachineType.
Note: All MachineTypes have at least 1 program.
for (int i = 0; i < dgvInput.Rows.Count; i++)
{
DataGridViewRow row = dgvInput.Rows[i];
int machineTypeId = Convert.ToInt32(row.Cells[1].Value);
Update update = new Update();
update.MachineType.Add(Check.prombase.MachineTypes.First(mt => mt.MachineTypeId == machineTypeId));
foreach (Program program in database.Programs)
{
if (program.ProgramVersion.Split('v')[0] == row.Cells[5].Value.ToString())
{ //If a program is added here, it will save it
update.Program.Add(program);
break;
}
}
if (update.Program.Count == 0)
foreach (Program program in database.Programs)
{ //When a program is added here, it will NOT save it
if (program.MachineType.MachineTypeId == machineTypeId)
{
update.Program.Add(program);
break; //When debugging it comes here everytime
}
}
//Here it is always: update.Program.Count = 1
database.AddToUpdates(update);
database.SaveChanges();
if (update.MachineType.Count == 0 || update.Program.Count == 0)
MessageBox.Show("This error is nevers shown!");
}
The problem is, it always says it has a program but in reality it is not.
What am I doing wrong that it wont add a Program to my Update?
edit VARAK:
After replacing the code it still won't save it, also added this at the end
reloadDatabase();
foreach(Update update in database.Updates)
if (update.Program.Count == 0)
MessageBox.Show("This can't be happening");
Please try this:
for (int i = 0; i < dgvInput.Rows.Count; i++)
{
DataGridViewRow row = dgvInput.Rows[i];
int machineTypeId = Convert.ToInt32(row.Cells[1].Value);
Update update = new Update();
update.MachineType.Add(Check.prombase.MachineTypes.First(mt => mt.MachineTypeId == machineTypeId));
var programVal = row.Cells[5].Value.ToString() + "v";
var program = database.Programs.FirstOrDefault(prog => prog.ProgramVersion.StartsWith(programVal));
if (program == null)
program = database.Programs.First(prog => prog.MachineType.MachineTypeId == machineTypeId);
update.Program.Add(program);
database.AddToUpdates(update);
database.SaveChanges();
//This will never show an error as the update that you are accessing here is the one you created in memory (Not the one in the DB)
if (update.MachineType.Count == 0 || update.Program.Count == 0)
MessageBox.Show("This will never show!");
//To get the error, pull the update from the database again
var updateNew = database.Updates.First(upd => upd.UpdateId == update.UpdateId);
if (updateNew.MachineType.Count == 0 || updateNew.Program.Count == 0)
MessageBox.Show("This will show if prog was not saved");
}
This code should be more efficient and might shed a bit more light if it doesn't work.
Finally found the solution, as you can see in my model the Program can have 1 Update, so when a new Update gets created the with the same Program as another Update, that other Update will lose the Program connected.