I have a gridview that is bound to a sql database. As the user enters data they must indicate whether that cell's information is complete or not. To do this they enter /end/ at the end of their statement and it will automatically change the cell color. If nothing is entered then nothing happens.
Here is the code:
if (dataItem != null)
{
var label = dataItem["Status"].FindControl("Statuslbl") as Label;
if (label != null)
{
var item = dataItem;
var text = label.Text;
if (text.Contains("/end/"))
{
item["Status"].BackColor = Color.Lime;
item["Status"].Text = item["Status"].Text.Replace(#"/end/", #"");
}
else
{
item["Status"].BackColor = Color.Salmon;
}
}
}
Instead of just hiding the '/end/' like I need it to, it hides the entire cells contents.
How can I go about fixing this?
Discovered all I would need to do would be the following to achieve my result:
if (text.Contains("/end/"))
{
item["Test"].BackColor = Color.Lime;
item["Test"].Text = label.Text.Replace("/end/", " ");
}
Really simple, I just needed to use label.Text.
Related
I have a datagridview showing installments of a loan. I created a datagridviewcheckbox column so then I can select all the installments i want to pay for.
This is a screen of the datagrid:
My issue is that I need to disable the checkboxes of the paid intallments. In this case, when "Restante" (what´s left to pay) is = 0.
I read some posts where they used the paint event to not show the checkbox cell, but i didnt like that solution. I thought of hiding the checkbox cell, but i don´t know if it is possible to do that.
Thats what i tried:
foreach (DataGridViewRow row in dgv_Cuotas.Rows)
{
if (Convert.ToDecimal(dgv_Cuotas.Rows[row.Index].Cells[17].Value) == 0)
{
dgv_Cuotas.Rows[row.Index].Cells[16].Visible = false;
}
}
Obviously this does not works, I get a compiler error message saying that the property is read only.
Does somebody knows how to set the checkbox cell to invisible?
Just in case, I attach the DataGridViewCheckboxColumn creation code:
DataGridViewCheckBoxColumn chbox = new DataGridViewCheckBoxColumn();
{
chbox.CellTemplate = new DataGridViewCheckBoxCell();
chbox.HeaderText = "";
chbox.Name = "Seleccionar";
chbox.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
chbox.FlatStyle = FlatStyle.Standard;
}
dgv_Cuotas.Columns.Insert(16, chbox);
dgv_Cuotas.Columns[16].DisplayIndex = 0;
EDIT:
Some considerations:
I use the cell content click event to handle the checkboxes, so readonly wont work. What I want is to hide the checkbox:
private void dgv_Cuotas_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == -1)
return;
if (dgv_Cuotas.Columns[e.ColumnIndex].Name == "Seleccionar")
{
DataGridViewRow row = dgv_Cuotas.Rows[e.RowIndex];
DataGridViewCheckBoxCell cellSeleccion = row.Cells["Seleccionar"] as DataGridViewCheckBoxCell;
int n_cuota = Convert.ToInt32(dgv_Cuotas[2, dgv_Cuotas.CurrentRow.Index].Value);
Cuota cuota_seleccionada = new Cuota();
cuota_seleccionada = Lista_cuotas.Where(x => x.num_cuota == n_cuota).First();
if (cellSeleccion != null && Convert.ToBoolean(cellSeleccion.Value) == true)
{
cellSeleccion.Value = false;
Actualizar_cuotas_seleccionadas(false, cuota_seleccionada);
}
else
{
if (cellSeleccion != null && Convert.ToBoolean(cellSeleccion.Value) == false)
{
cellSeleccion.Value = true;
Actualizar_cuotas_seleccionadas(true, cuota_seleccionada);
}
}
}
In the other hand, I´m already using the Onpaint event. Its inherited, thats why I´m trying to avoid using it.
Assign a value to the checkbox cell. Then Convert it to a TextBox with a new value.
Worked for me.
dataGridView1.Rows[row.Index].Cells[16].Value = false;
dataGridView1.Rows[row.Index].Cells[16] = new DataGridViewTextBoxCell();
dataGridView1.Rows[row.Index].Cells[16].Value = "";
Yes, you can do this by Converting the DataGridViewCheckBoxCell to DataGridViewTextBoxCell
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (dataGridView1.Rows[row.Index].Cells[17].EditedFormattedValue.ToString().Length == 0) // if (string.IsNullOrWhiteSpace(dataGridView1.Rows[row.Index].Cells[4].EditedFormattedValue.ToString()))
break;
if (Convert.ToDecimal(dataGridView1.Rows[row.Index].Cells[17].EditedFormattedValue) == 0)
{
dataGridView1.Rows[row.Index].Cells[16].Value = null;
dataGridView1.Rows[row.Index].Cells[16] = new DataGridViewTextBoxCell();
}
else
{
//dgv_Cuotas.Rows[row.Index].Cells[16] = new DataGridViewCheckBoxCell();
}
}
Use the cell's ReadOnly attribute to disable any modification.
If you want to turn it to hidden, you need to override the painting code for the cells.
Try to hide it and the value remains, which should prevent runtime errors.
dataGridView1.Rows[row.Index].Cells[16].Style.Padding =
new Padding(dataGridView1.Rows[row.Index].Cells[16].OwningColumn.Width, 0, 0, 0);
I took spajce's answer and tweaked it a bit to make it work for me.
for (var i = 0; i < datagridview1.Count; i++)
{
if ((bool)datagridview1[0, i])
{
datagridview1[0, i] = new DataGridViewTextBoxCell
{
Style = { ForeColor = Color.Transparent,
SelectionForeColor = Color.Transparent }
};
}
}
We're basically iterating through the rows and looking for a 'true' checked box. If it's checked then we're converting the box to a text box and setting its text color to Transparent so the cell looks empty. I hope this helps everyone who had this problem, I spent hours trying to find a workable answer.
There are several ways to accomplish what you want.
For example, you can use the Readonly property of the cell to avoid the user to change the values and change the appeareance of the control to look grayed:
C# DataGridViewCheckBoxColumn Hide/Gray-Out
A simple and effective alternative is to use the chkbox ThreeState property. In code below, if my object does not have an email address, then I don't want to allow the user to tick the checkbox for sending email. To do this, the check box value is set to Unknown and read-only, which means it is displayed as "unselectable" and user cannot modify.
chk = DirectCast(row.Cells(m_idxEmailChecked), DataGridViewCheckBoxCell)
If String.IsNullOrEmpty(contact.EmailAddress) Then
chk.Value = enumTristate.Unknown
chk.ReadOnly = True
Else
chk.ThreeState = False
End If
Note this also requires several associated ThreeState properties to be set on the checkbox.
.ValueType = GetType(enumTristate)
.TrueValue = enumTristate.True
.FalseValue = enumTristate.False
.IndeterminateValue = enumTristate.Unknown
.ThreeState = True
Good luck.
I tried Charlie's way:
dataGridView1.Rows[row.Index].Cells[16].Value = false;
dataGridView1.Rows[row.Index].Cells[16] = new DataGridViewTextBoxCell();
dataGridView1.Rows[row.Index].Cells[16].Value = "";
I got fewer errors, but still kept getting them. So I tried to instantiate the new DataGridViewTextBoxCell separately, and that did the trick for me (I didn't need to set the checkbox cell value either):
DataGridViewTextBoxCell c = new DataGridViewTextBoxCell();
c.Value = "";
dataGridView1.Rows[row.Index].Cells[16] = c;
Hope that helps someone!
I am trying to change the color of an empty textbox, I have more than one textbox on this form and i wish to highlight the empty one when a user clicks submit. I have written the loop below which is in my btnSubmit function after checking if all the textbox have a value. Can anyone help in completing this loop for me??
foreach (Control txtbxs in this.Controls)
{
if (txtbxs is TextBox)
{
var TBox = (TextBox)txtbxs;
if (TBox.Text == string.Empty)
{
TBox.ForeColor = Color.Red;
}
}
}
lblTopError.Text = "Please fill in the missing billing information";
pnlTopError.Visible = true;
When your string is empty, changing the ForeColor will do nothing since you don't have Text to display in red. Consider using BackColor and remember to have an event when text is entered to switch it back to the appropriate BackColor.
If this is what you are trying to do, have you considered using the error provider? this would help you to signal the user and prompt them to put in the information.
errorProvider= new System.Windows.Forms.ErrorProvider();
errorProvider.BlinkRate = 1000;
errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.AlwaysBlink;
private void TextValidated(object sender, System.EventArgs e)
{
var txtbox = Sender as TextBox;
if(IsTextValid(txt))
{
// Clear the error, if any, in the error provider.
errorProvider.SetError(txtbox, String.Empty);
}
else
{
// Set the error if the name is not valid.
errorProvider.SetError(txtbox, "Please fill in the missing billing information.");
}
}
You can apply any CSS you want like this:
TBox.Attributes.Add("style", "color: red; border: solid 1px #FC3000")
I would use this instead of:
TBox.ForeColor = Color.Red;
Well since there aren't much textboxes in this form, i went the easy route and it worked, code bellow:
List<TextBox> boxes = new List<TextBox>();
if (string.IsNullOrWhiteSpace(txtFname.Text))
{
//highlightTextBox= txtFname;
boxes.Add(txtFname);
}
if (string.IsNullOrWhiteSpace(txtLname.Text))
{
//highlightTextBox = txtLname;
boxes.Add(txtLname);
}
if (string.IsNullOrWhiteSpace(txtAddOne.Text))
{
//highlightTextBox = txtAddOne;
boxes.Add(txtAddOne);
}
if (string.IsNullOrWhiteSpace(txtTown.Text))
{
//highlightTextBox = txtTown;
boxes.Add(txtTown);
}
if (string.IsNullOrWhiteSpace(txtPostCode.Text))
{
//highlightTextBox = txtPostCode;
boxes.Add(txtPostCode);
}
foreach (var item in boxes)
{
if (string.IsNullOrWhiteSpace(item.Text))
{
item.BackColor = Color.Azure;
}
}
lblTopError.Text = "Please fill in the missing billing information highlighted below";
pnlTopError.Visible = true;
I have a loop going through each of my textboxes in Form1 and getting the tag for them as i will need to compare object IDs. in situations where an object already exist in one of my textboxes, i do not want to allow the user to add this object again, but if this object does not exist in any of the textboxes, only then can the user add this item.
I have tried it with this loop below but it doesnt seem to work as it keeps telling me "Object reference not set to an instance of an object." on this line if (resval.types.xan_ID == tbItems.types.xan_ID)
after i get the message box which i want, how can I change this code to achieve this goal.
// Get the name which will be passed into the textbox
var resval = form2result.getValue();
//go through each of my textbox
foreach (TextBox tb in TextBoxList)
{
var tbItems = (ReportItems)tb.Tag;
if (tb.Text != "")
{
//if the item returned is the same as an item in the textbox
if (resval.types.xan_ID == tbItems.types.xan_ID)
{
// display this message and break out of the loop
MessageBox.Show("You have previously selected this report, please chose another");
break;
}
// otherwise add the item into the textbox.
else
{
// otherwise add name to the textbox
_dict[sender].Text = resval.ToString();
}
}
}
ReportItems
public class ReportItems
{
public DataSet1.xspGetAnalysisTypesRow types { get; set; }
//Analysis types or Reports
public ReportItems(DataSet1.xspGetAnalysisTypesRow analysisTypes)
{
types = analysisTypes;
}
//Return the name of this type.
public override string ToString()
{
return this.types.xan_Name;
}
}
getValueFunction (This is in a different form)
public ReportItems getValue()
{
ReportItems selection = (ReportItems)reportListBx.SelectedItem;
// if user has selected a value
return selection;
}
I'm not sure what the link is between _dict[sender] and TextBoxList but you haven't set the Tag as the same point as setting the text. Assuming these are referring to the same object this will cause an error the next time you use this method as you'll have a text box with no tag.
// Get the name which will be passed into the textbox
var resval = form2result.getValue();
// The user didn't select anything somehow.
if (resval == null)
{
MessageBox.Show("Nothing Selected");
return;
}
// resval hasn't been setup correctly.
if (resval.types == null)
{
MessageBox.Show("Internal Error");
return;
}
Boolean alreadyExists = false;
//go through each of my textbox
foreach (TextBox tb in TextBoxList)
{
var tbItems = (ReportItems)tb.Tag;
//The Textbox must contain text and tbItems must not be null
if (tb.Text != "" && tbItems != null)
{
//The tag has been set, but somehow the types are null?
if (tbItems.types == null)
{
MessageBox.Show("Internal Error");
break;
}
//if the item returned is the same as an item in the textbox
if (resval.types.xan_ID == tbItems.types.xan_ID)
{
alreadyExists = true;
// display this message and break out of the loop
MessageBox.Show("You have previously selected this report, please chose another");
break;
}
// otherwise add the item into the textbox.
}
}
if (!alreadyExists)
{
// otherwise add name to the textbox
_dict[sender].Text = resval.ToString();
//set the tag?
_dict[sender].Tag = tbItems;
}
// Get the name which will be passed into the textbox
var resval = form2result.getValue();
ArrayList arrayList = new ArrayList();
//go through each of my textbox
foreach (TextBox tb in TextBoxList)
{
var tbItems = (ReportItems) tb.Tag;
if (tb.Text != "") return;
//if the item returned is the same as an item in the textbox
/* Try this if the below line doesnt work
if(string.IsNullOrEmpty(resval.types.xan_ID) || string.IsNullOrEmpty(tbItems.types.xan_ID) return;
if (resval.types.xan_ID == tbItems.types.xan_ID) return;
*/
if ((string)(resval.types.xan_ID) == (string)(tbItems.types.xan_ID)) return;
// otherwise add the item into the textbox.
// otherwise add name to the textbox
arrayList.Add(resval.ToString());
}
foreach (var arr in arrayList)
{
// something = arr.ToString();
}
You can handle onmouseover or onclick event of a Textbox(on which user focus to add) by using jquery and can check whether a user add an object to previous Textboxes or not.
I'm having a DropdownList and when its Selected Value is changed (for ex: 0 ) I need to set the visible property of a Panel to True and the visible property of another Panel to False.
and when another Value is selected I need to do Vice Versa Using JAVASCRIPT.
I'm currently achieving this but the space remains as it is. How can i remove the spaces also.
can anyone help me??
I'm attaching the code also.
function visible(val) {
var ddl = document.getElementById("ddl_IDProof");
var selectedFilterType = drpFilterType.options[ddl.selectedIndex].value;
if (selectedFilterType == "0") {
document.getElementById("pnl1").style.visibility = "visible";
document.getElementById("pnl2").style.visibility = "hidden";
}
else {
document.getElementById("pnl1").style.visibility = "hidden";
document.getElementById("pnl2").style.visibility = "visible";
}
}
Use display instead of visibility.
This will hide the entire element:
// Show pnl1 (maybe you have to use inline or inline-block insdead of block)
document.getElementById("pnl1").style.display = "block";
// Hide pnl2
document.getElementById("pnl2").style.display = "none";
I want to allow the user to input only text that is validated by the TextBox binding validation rules. I figured out a way of doing that:
public static void PreviewTextChanged(
object sender,
PreviewTextChangedEventArgs e)
{
var textBox = e.Source as TextBox;
var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
if (!ReferenceEquals(null, bindingExpression))
{
// save original parameters for possible restoration
var originalSelectionStart = textBox.SelectionStart;
var originalSelectionLength = textBox.SelectionLength;
var originalText = textBox.Text;
// check validation
textBox.Text = e.Text;
if (!bindingExpression.ValidateWithoutUpdate())
{
// restore original values
textBox.Text = originalText;
bindingExpression.UpdateSource();
textBox.SelectionStart = originalSelectionStart;
textBox.SelectionLength = originalSelectionLength;
}
else
{
// correct the selection
var selectionStart = originalSelectionStart +
originalSelectionLength +
e.Text.Length -
originalText.Length;
textBox.SelectionStart = Math.Max(selectionStart, 0);
textBox.SelectionLength = 0;
}
e.Handled = true;
}
}
The code above works. But it would be much simpler, and less bug-prone, if I could find a way to check if the new value is valid without updating the binding target. Is there one?
I think it's easier in this case to relay on Binding Converters.
The converter will be called every time the data should be assigned to the binded field.
Inside methods of it, you can validate the input of the data and based on validation result return or old data (cause validation fails) recovered from ModelView or accept it, in case when validation succeeded.
Hope this helps.