Bind Dictionary inside a for loop - c#

Player.Scores is a Dictionary<int, int?>. This code renders the correct value from the dictionary. But when the input value changes, hole variable is the same as the for loop ended at. If the course has 18 holes, the loop ends when reaching 19. All bindings goes to player.Scores[19] and that adds an extra key to the dictionary.
How do I bind the dictionary to it's key when inside a loop?
<tbody>
#for (int hole = 1; hole <= Course.Holes; hole++)
{
<tr>
<td>#hole</td>
#foreach (var player in Players)
{
<td><input #bind="player.Scores[hole]" /></td>
}
</tr>
}
</tbody>

#for (int hole = 1; hole <= Course.Holes; hole++)
{
int holeCopy = hole; // let holeCopy be captured instead of hole
<tr>
<td>#hole</td>
#foreach (var player in Players)
{
<td><input #bind="player.Scores[holeCopy]" /></td>
}
</tr>
}
#bind uses a lambda function when it is compiled to C#.
The problem is called 'capturing the loop var', you can google that.
And it won't hurt to use <tr #key="hole">

Related

Check if a foreach loop with a keyvaluepair is the last item and then do something in c#

I have a specific question relating a foreach loop in C# and Blazor Web Assembly.
This is my foreach loop containing a keyvaluepair:
`
#foreach (KeyValuePair<int, string> pair in detail.Years2Value.OrderBy(x => x.Key))
{
<td colspan="1"><input type="text" class="radius form-control" style="background-color:transparent; border:0.1px" readonly="readonly" value=#pair.Value></td>
}
<td colspan="1" class="border-left border-right"></td>
`
I want to display all values in a range and in a Region. After each region it should create an empty row to make it look better and more organized. Thats why I am adding a td after the foreach.
This creates following problem: --> See Picture below!
after the last foreach in my last Region is done, I don't want to create a new td but I don´t know how to achieve this.
If I just delete the line of code with the td after the foreach then all regions will stick more or less together and it don´t look so good anymore because the missing "separation" of each region.
Is there a way to break the foreach only after the 3rd region is done and then don´t do the new td with an if sentence or something similar?
I hope you guys can help me here. Sorry if there is any information missing or something is not clear. I will try to explain it again if something is not clear.
Thank you
Here is the sample code
int i = 1;
#foreach (KeyValuePair<int, string> pair in detail.Years2Value.OrderBy(x => x.Key))
{
<td colspan="1"><input type="text" class="radius form-control" style="background-color:transparent; border:0.1px" readonly="readonly" value=#pair.Value></td>
if(i < detail.Years2Value.Count)
{
<td colspan="1" class="border-left border-right"></td>
}
i++;
}
I hope I understand your example well:
You could use for-loop and iterate through the items with index like the following.
#*Loop through all the KeyValuePairs in the Dictionary<int,string> *#
#for (int i = 1; i < orderedYearsToValue.Count(); i++)
{
<td colspan="1">
#*Select element and its value at the current index*#
<input type="text" class="radius form-control" style="background-color:transparent; border:0.1px" readonly="readonly" value=#orderedYearsToValue.ElementAt(i).Value>
</td>
#*If the current index is not at the last item, add an empty line *#
#if (i != orderedYearsToValue.Count()-1)
{
<td colspan="1" class="border-left border-right"></td>
}
}
#code {
private Dictionary<int, string> orderedYearsToValue;
... your code
private void OrderValues() {
orderedYearsToValue = detail.Years2Value.OrderBy(x => x.Key);
}
}
UPDATE after update of the original code:
The empty TD is done after every region. Therefore the for-loop should be done on the top level and TD only added after region is finished, instead of the nested loop.
Simplified code (use the logic from above):
for (int i = 0; i < myOrderedCountries.Count(); i++)
{
if(detail != null)
{
if(isSpecialist)
{
foreach(KeyValuePair<int, string> in myOrderedYearsToValue)
{
<td colspan="1"><input type="text" ...></td>
}
}
else
{
foreach(KeyValuePair<int, string> in myOrderedYearsToValue)
{
<td colspan="1"><input type="different text" ...></td>
}
}
if(i < myOrderedCountries.Count() - 1) {
<td colspan="1" class="border-left border-right"></td>
}
}
}
and even nicer would be to move the if part into the nested for-loop like this:
for (int i = 0; i < myOrderedCountries.Count(); i++)
{
if(detail != null)
{
foreach(KeyValuePair<int, string> in myOrderedYearsToValue)
{
if(isSpecialist)
{
<td colspan="1"><input type="text" ...></td>
}
else
{
<td colspan="1"><input type="different text" ...></td>
}
if(i < myOrderedCountries.Count() - 1) {
<td colspan="1" class="border-left border-right"></td>
}
}
}

Blazor dynamically generated table rows

I created an sample c# blazor (server-side) app to practice a little.
I try to generate table rows dynamically for a calendar but i run into a problem there.
<table class="table">
<thead>
<tr>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
</thead>
<tbody>
<tr>
#* currentDateTimeValues is a list with DateTime objects *#
#foreach (var item in currentDateTimeValues)
{
#if (counter % 7 == 0 && counter > 0)
{
#:</tr><tr>
}
counter++;
<td>#item.ToString("dd.MM.yyyy")</td>
}
</tr>
</tbody>
</table>
After 7 cells a new row should be created but it doesn't. The cells go straight ahead without linebreak.
Maybe you guys have any idea.
UPDATE:
In the meantime I've created a workaround because I think that blazor can't handle the </tr><tr>
My currentDateTimeValues-List now contains week objects
<tbody>
#* currentDateTimeValues is a list with Week objects *#
#foreach (var week in currentDateTimeValues)
{
<tr>
<td>#week.Monday</td>
<td>#week.Tuesday</td>
<td>#week.Wednesday</td>
<td>#week.Thursday</td>
<td>#week.Friday</td>
<td>#week.Saturday</td>
<td>#week.Sunday</td>
</tr>
}
</tbody>
I think the solution you are trying isn't possible in Blazor at the moment. Why not use two loops to create the calendar. Something like:
#while (counter < currentDateTimeValues.Length)
{
<tr>
#{
var i = 0;
if (i < 7 && counter + i < currentDateTimeValues.Length)
{
<td>#currentDateTimeValues[counter + i].ToString("dd.MM.yyyy")</td>
i++;
}
}
</tr>
counter += 7;
}

Autoincrement won't work inside foreach in a table

Right now I'm trying to add a feature to my table.
It's being done inside a cshtml C# MVC ASP.NET Enviroment.
#{
dt_Table = ds_Set.Tables[1];
foreach (System.Data.DataRow dr in dt_Table.Rows)
{
int autoincrement = 0;
string nombre = dr["Nombre"].ToString();
<tr>
<td align="center">#(autoincrement++)</td>
<td align="center">#nombre</td>
</tr>
}
}
How do I add auto increment or ++ to the value?
Right now like that it just prints "1" on each row of the table :(
How can I solve this?
The variable autoincrement is scoped to the foreach loop block so it is allocated and released each iteration. Declare the variable outside of the foreach loop (or you can use a for loop):
for( var i = 0; i < dt_Table.Rows.Count; ++i )
{
var dr = dt_Table.Rows[i];
var nombre = dr["Nombre"].ToString();
<tr>
<td align="center">#i</td>
<td align="center">#nombre</td>
</tr>
}
Thanks for the quick answer, can't believe I could't figure this out
#{
int autoincrement = 1;
dt_Table = ds_Set.Tables[1];
foreach (System.Data.DataRow dr in dt_Table.Rows)
{
string nombre = dr["Nombre"].ToString();
<tr>
<td align="center">#(autoincrement++)</td>
<td align="center">#nombre</td>
</tr>
}
}

Issue with going through a list in view of mvc c#

I am making an mvc application-c# that uses data from a database and I am having trouble looping through the list in the view that is part of my model.
This is my code in the view:
#foreach (var item in Model.communications)
{
<tr>
int i = 0;
<td>#Model.student.FirstName #Model.student.LastName</td>
<td>#item.Notes</td>
<td>#item.Date</td>
<td>
#Model.employeeName[i]
</td>
</tr>
}
try to replace your code with this
use item variable instead of Model so you can access values
#foreach (var item in Model.communications)
{
<tr>
int i = 0;
<td>#item.student.FirstName #item.student.LastName</td>
<td>#item.Notes</td>
<td>#item.Date</td>
<td>
#item.employeeName[i]
</td>
</tr>
}

Appending variable in for loop to mvc4 razor helper

I have a number of fields in my model which are named as such model.var_1, model.var_2, ... model.var_30.
I am trying to put these in a table so I am using a for loop as so.
<table>
<tr>
<th>Category</th>
<th>Description</th>
#for (int i = 1; i <= Model.Total; i++)
{
<th class="ali_day#(i)">Day #i</th>
}
</tr>
<tr>
<th>Intubated</th>
<th></th>
#for (int i = 1; i <= Model.Total; i++)
{
<th>#Html.EditorFor(model => model.var_#(i))
#Html.ValidationMessageFor(model => model.var_#(i))</th>
}
</tr>
</table>
However, var_#(i) doesn't seem to be valid. Is there a way to append this loop counter so I can get my variable name while using an html helper?
Use the editor helper overload that takes a string, that way you can use string concatenation to create the variable name.
#Html.Editor("var_" + i)
and the same for the validation message
#Html.ValidationMessage("var_" + i)

Categories

Resources