How to make a checkbox disabled without using any specific condition? - c#

I have a checkbox whose value is handled from the DB on the basis of the column isAllow. We have 5 names and corresponding to these name we have diff isAllow property. If the value of isAllow is true then the checkbox get checked.
For four names, I have to make the checkbox as checked, but for one specific name out of 5, I have to mark the checkbox as disabled as well. I can achieve this by adding a condition as:
if(name=="Josh" && isAllow)
{
chkBrand.Enable=false;
chkBrand.Checked=true;
}
I dont want to use the above condition here. I just want to get the checkbox as disable for a specific name without the condition.
Below is the code that I have used:
bool isAllow = false;
bool SigCard = false;
List<AOTLuAffinity> oAotluAffinity = bsAffinity.DataSource as List<AOTLuAffinity>;
foreach (AOTLuAffinity oAffinity in oAotluAffinity)
{
if (oAffinity.Name == comboName.SelectedValue.ToString())
{
isAllow = oAffinity.isAllowName;
signCard = AOTHelper.GetHasSigCardValue(workflowid, Acct.AffinityNum, comboPaBranch.SelectedValue.ToString(), Applicants.AffinityNum, isSignCard, isAllow );
if (isAllow)
{
chkBrand.Checked=true;// here for a specific name, I want to make the checkbox as disabled, but I dont want to use the condition.
}
else
{
chkBrand.Checked=false;
}
break;
}
}
I am finding a hard time in getting this. Any help will be great.

I think the right approach here is to add a new field to the database, isDisabled, and then in your loop evaluate that field:
...
else
{
chkBrand.Checked=false;
}
if (oAffinity.isDisabled)
{
chkBrand.Enabled = false;
}
break;

You can use LINQ conditions to check specific names on a list. You must declare a list like this:
List<Person> peopleList = new List<Person>();
And here is your condition code:
foreach (AOTLuAffinity oAffinity in oAotluAffinity)
{
if (oAffinity.Name == comboName.SelectedValue.ToString())
{
isAllow = oAffinity.isAllowName;
signCard = AOTHelper.GetHasSigCardValue(workflowid, Acct.AffinityNum, comboPaBranch.SelectedValue.ToString(), Applicants.AffinityNum, isSignCard, isAllow );
chkBrand.Checked =
peopleList
.Count(c => c.Name == comboName.SelectedValue.ToString()) > 0 ? true : false;
break;
}
}

Loop on the items you got from database and each time read value (isAllow),then
chkBrand.Checked=isAllow;

Related

How to create a method where multiple controls are false in an "if" statement for C#?

What is the best way to simplify this (via method creation or otherwise):
if ((radioButton1.Checked == false) && (radioButton2.Checked == false) && (radioButton1.Checked == false) && ...more similar controls... && ((radioButton99.Checked == false))
{
MessageBox.Show("Please select an option!);
}
Thank you for your consideration. Apologies for any inconvenience or grievances caused.
You could put all those controls in a List and then check whether any of the controls in the list is checked. This can be done in several ways. Below examples of two of those.
Example using loop:
bool optionSelected = false;
foreach(var control in controls) // the List is in this case called controls
{
if(control.Checked)
{
optionSelected = true;
}
}
// Check the boolean
Example using System.Linq:
if(!controls.Any(c => c.Checked))
{
MessageBox.Show("Please select an option!);
}
You need to add your controls into a public collection to simply iterate them.
if you have a bunch of the same type controls, it's better to put them into a array in your form's constructor :
CheckBox[] MyBoxes = new CheckBox[]{ check01, check02 , ... }
// MyBoxes is filled at Form_Load and it's usable in throughout of the form
bool result = true;
for(int i=0; i<MyBoxes.Length; i++)
{
if (MyBoxes[i].Checked == false)
{ result = false; break; }
}
another solution is to iterate whole controls on the form:
bool result = true;
for(int i=0; i<this.Controls.Count; i++)
{
if (this.Controls[i] is CheckBox)
{
if ((this.Controls[i] as CheckBox).Checked == false)
{ result = false; break; }
}
}
If you have lots of controls (in this case - RadioButtons), then you can use the following trick - Tag property.
To summarize:
1) Set Tag property with the some string to differentiate from other controls (in particular, there may be the case when not all the controls of one type must be processed).
2) Collect these controls with defined string in Tag and process them.
In your particular case, you can set the string ToCheck in Tag and then check whether all RadioButtons are checked:
// Collect controls with defined string in Tag property
var radioButtons = this.Controls
.OfType<RadioButton>() //Filter controls by type
.Where(rb => ((string)rb.Tag) == "ToCheck"); //Get controls with defined string in Tag
// Check whether all RadioButtons are checked
bool allChecked = radioButtons.All(rb => rb.Checked);
The possible approach could be to introduce variable for condition validation
bool optionIsSelected = ((radioButton1.Checked == true) || (radioButton2.Checked == true)...;
And then use it in if:
if (!optionIsSelected)
{
MessageBox.Show("Please select an option!);
}
private bool AreAllFalse(params bool[] thingsToCheck)
{
return things.All(t => !t);
}
Usage
if (AreAllFalse(radioButton1.Checked,radiobutton2.Checked, etc)
{
//Do what you want
}
The benefit of using the params key word is that it creates the array for you when you call the method. It also allows you to pass in just one thing to check if you want. While that would be quite pointless here, it just keeps things felxible and is something worthwhile knowing

Make null columns invisible in DataGridView

I have a datagridview in WinForm C# application called custFleetDataGrid
I've tried to create a method which will set each column to invisible if all the rows are null or ""
The code does not work as expected, columns with blank data remain in the grid view.
I'm calling Code like this
custFleetDataGrid.RemoveEmptyColumns();
Method I'm using to remove NullColumns
public static class ExtensionGridView
{
public static DataGridView RemoveEmptyColumns(this DataGridView grdView)
{
foreach (DataGridViewColumn clm in grdView.Columns)
{
bool notAvailable = true;
foreach (DataGridViewRow row in grdView.Rows)
{
if (row.Cells[clm.Index].Value == null || row.Cells[clm.Index].Value.ToString() != "")
{
notAvailable = false;
break;
}
}
if (notAvailable)
{
grdView.Columns[clm.Index].Visible = false;
}
}
return grdView;
}
}
could this be because the compiler is trying to convert a null value to a string?
Correct, that's the exact case. Just it's not the compiler, but the code you have written.
I would suggest you encapsulating the empty cell logic into separate extension method inside the ExtensionGridView class:
public static bool IsEmpty(this DataGridViewCell cell)
{
var value = cell.Value;
return value == null || value == DBNull.Value || (value as string) == string.Empty;
}
Then you can use simple LINQ to determine the empty columns:
public static IEnumerable<DataGridViewColumn> EmptyColumns(this DataGridView gridView)
{
return gridView.Columns.Cast<DataGridViewColumn>()
.Where(c => gridView.Rows.Cast<DataGridViewRow>().All(r => r.Cells[c.Index].IsEmpty()));
}
Then your method could be simply like this:
public static DataGridView RemoveEmptyColumns(this DataGridView gridView)
{
foreach (var column in gridView.EmptyColumns())
column.Visible = false;
return gridView;
}
If Value is null, you'll get a NullReferenceException if using ToString() on it. So you have to null-check the value before using ToString().
Go like this:
// IF (Value is empty => use "").ToString() <-- IsNullOrEmpty
if (!string.IsNullOrEmpty(row.Cells[clm.Index].Value ?? "").ToString())
{
notAvailable = false;
break;
}
Check the details about ?? here.
Its the same as:
// If not null
if(row.Cells[clm.Index].Value != null)
{
// If string of value is empty
if(row.Cells[clm.Index].Value.ToString() != "")
{
notAvailable = false;
break;
}
}
Away from your problem here's a short version of everything:
public static DataGridView RemoveEmptyColumns(this DataGridView grdView)
{
for (int i = 0; i < grdView.ColumnCount; i++)
{
// On each iteration get all values of a column
IEnumerable<string> column = grdView.Rows.Cast<DataGridViewRow>().Select(row => (string)row.Cells[i].Value);
// If there is no value with length > 0 => visible = false
if (!column.Any(x => x.Length > 0)) { grdView.Columns[i].Visible = false; }
}
return grdView;
}
Instead of iterating trough each row i'd let my select statement do it like so:
SELECT some columns FROM yourtable WHERE thecolumn IS NOT NULL
Your problem is that you are checking if row.value.toString() is null or empty. If valueis null, when it tries to get the toString() to check if its null or empty it can't.
Change your if statement to:
if (row.Cells[clm.Index].Value != null || row.Cells[clm.Index].Value.toString()!="")
{
//Code
}
Important note:
In C# (and most modern languages) you have two opetaors for OR (| and ||) and two for AND(& &&). If its just one (&/|) it will check both sides but if it have two (&&/||) if the first condetin determines eveirthing (a true for OR or a false for AND) it will not check the second one.
This gives you more rendiment but also is usefull for not having nullpointerexeptions. If it's null, it will not check the second part and it will not explote. If you just put one it will say "Yes, is null, lets check if the string is also "" and will throw a NulPointerExeption.

is there a way to set a variable to something at the end of foreach loop if condition not met in C#?

foreach (Objecta a in aList())
{
foreach (Objectb b in bList)
{
if (a.variable != b.variable1 && a.variable() != b.variable2)
{
a.setVariable("Error");
}
}
}
The problem I am getting is that it goes through the foreach loop the first time and it sets variable to error without checking if other values (when it goes through the loop again) finds a match.
What I would like is to wait until it goes through all the lists and at the last foreach loop iteration if nothing in aList matches the variable target && variable source in bList then finally set it to Error flag.
Any suggestions to get around this will be appreciated.
Try doing it the other way around. Search for a match instead of searching for non-matches.
foreach (Objecta a in aList())
{
bool foundMatch = false;
foreach (Objectb b in bList)
{
if (a.variable == b.variable1 || a.variable() == b.variable2)
{
foundMatch = true;
break;
}
}
if (!foundMatch)
{
a.setVariable("Error");
}
}
I think this is what you are looking for. So if StoreList is the outer loop and LinkList is the inner loop. You want to search all the links to see if there's an ID that matches the store ID. If you find a match, stop searching the links. After the search through the links, set an error on the store if there was no match, then go to the next store.
foreach (Objecta a in aList())
{
var foundMatch = false;
foreach (Objectb b in bList)
{
if (a.variable == b.variable1 || a.variable() == b.variable2)
{
fondMatch = true;
break;
}
}
if (!foundMatch) a.setVariable("Error");
}
I think you want something like this:
First select all the item values from aList and bList and put them in a seperate array:
var aVals = aList.Select(x=>x.value1).ToArray();
var bListVals1 = bItems.Select(x=>x.value1).ToArray();
var bListVals2 = bItems.Select(x=>x.value2).ToArray();
var bVals = bListVals1.Concat(bListVals2);
Then, get the values both lists have in common:
var correctVals = bVals.Intersect(aVals);
These are the correct values and so all the other values are wrong:
var wrongVals = aVals.Except(correctVals);
Now you have the values that are wrong and can act accordingly:
wrongAItems = aList.Where(a => wrongVals.Contains(a.value));
foreach(wrongA in wrongAItems){
wrongA.setVariable("Error");
}
foreach (Store s in processFlowStores.getStoresList())
{
if (!processFlowLinks.Any(l => s.getNodeId() == l.getLinkSource() ||
s.getNodeId() == l.getLinkTarget()))
{
s.setID("Error: FailedOperation Error - 123.123.121");
}
}
EDIT: more compact solution using Linq. Basically, if none of the links has it as either source or target, mark it as error.

DevExpress XtraGrid force filter to display individual values for RepositoryItemCheckedComboBoxEdit column

I have added a column with RepositoryItemCheckedComboBoxEdit as an editor. Each row for that column can feature one or more entries from a predefined list of categories (let's call them Category1, Category2 and Category3) which are strings and are read from the database.
My problem is that the filter will list options such as: "Category1; Category2" as well as "Category1" or "Category1; Category2; Category3", depending on what it finds in the grid for said column (if one of the rows has all three categories selected that will be considered an individual filter option, instead of breaking down the value into its components).
I would like the filter to only list single values, instead of combinations, but I'm unable to find a solution for that. I have tried using the ShowFilterPopupCheckedListBox event in order to manipulate the filter contents, but now filtering has stopped working for that column altogether.
Here is my code:
void gridView_ShowFilterPopupCheckedListBox(object sender, DevExpress.XtraGrid.Views.Grid.FilterPopupCheckedListBoxEventArgs e)
{
List<CheckedListBoxItem> atomicValues = new List<CheckedListBoxItem>();
if (e.Column.FieldName != "CategoryCollection") { return; }
for (int i = 0; i < e.CheckedComboBox.Items.Count; i++)
{
CheckedListBoxItem item = e.CheckedComboBox.Items[i];
string itemValue = (string)(item.Value as FilterItem).Value;
string[] atomicItemValues = itemValue.Split(';');
foreach (string atomicValue in atomicItemValues)
{
string trimmedAtomicValue = atomicValue.Trim();
atomicValues.Add(new CheckedListBoxItem(trimmedAtomicValue));
}
}
List<CheckedListBoxItem> distinctAtomicValues = atomicValues.GroupBy(x => x.Value).Select(group => group.First()).OrderBy(x => x.Value).ToList();
e.CheckedComboBox.Items.Clear();
foreach (CheckedListBoxItem atomicItem in distinctAtomicValues)
{
e.CheckedComboBox.Items.Add(atomicItem);
}
}
As I know, checked filter dropdown list does not allow to add custom items.
As an alternative solution, you can use the Auto Filter Row for filtering a column by using an in-place CheckedComboBoxEdit:
Enable GridView.OptionsView.ShowAutoFilterRow property to true.
Assign in-place CheckedComboBoxEdit to auto filter row cell
Handle the GridView.CustomRowCellEdit event in the following way:
-
private void gridView_CustomRowCellEdit(object sender, DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs e)
{
if (e.Column.FieldName == "YourField" && e.RowHandle == GridControl.AutoFilterRowHandle)
{
e.RepositoryItem = repositoryItemCheckedComboBoxEdit;
}
}
There are no build-in functions in GridView, so you need to create your custom descendant from GridView class.
You need to apply your custom filter criteria, because default GridView are applying equals operator for checked filter, but you need to use contains criteria. For this you need to ovveride ApplyCheckedColumnFilter method of GridView.
Also if you want to show currently applied filters in popup, then you need to update FilterValues property of CheckedColumnFilterPopup.RepositoryItemFilterComboBox object. You can get this object from FilterPopupCheckedListBoxEventArgs.CheckedComboBox property by casting it to CheckedColumnFilterPopup.RepositoryItemFilterComboBox.
Here is example:
Custom GridView descendant:
public class CustomGridView : GridView
{
protected override void ApplyCheckedColumnFilter(GridColumn column, object stringValues, List<object> checkedValues)
{
if (column.ColumnEdit is RepositoryItemCheckedComboBoxEdit)
{
var groupOperator =
new GroupOperator(
GroupOperatorType.Or,
from checkedValue in checkedValues
where checkedValue != null
select
new FunctionOperator(
FunctionOperatorType.Contains,
new OperandProperty(column.FieldName),
new OperandValue(checkedValue)));
ColumnFilterInfo filterInfo;
switch (groupOperator.Operands.Count)
{
case 0:
filterInfo = new ColumnFilterInfo();
break;
case 1:
filterInfo = new ColumnFilterInfo(groupOperator.Operands[0]);
break;
default:
filterInfo = new ColumnFilterInfo(groupOperator);
break;
}
column.FilterInfo = filterInfo;
}
else
base.ApplyCheckedColumnFilter(column, stringValues, checkedValues);
}
}
ShowFilterPopupCheckedListBox event handler method:
private void gridView1_ShowFilterPopupCheckedListBox(object sender, FilterPopupCheckedListBoxEventArgs e)
{
if (!(e.Column.ColumnEdit is RepositoryItemCheckedComboBoxEdit)) { return; }
var distinctAtomicValues =
(from value in
(from atomicItemValues in
from item in e.CheckedComboBox.Items.OfType<CheckedListBoxItem>()
let itemValue = (string)(item.Value as FilterItem).Value
where itemValue != null
select itemValue.Split(';')
from atomicValue in atomicItemValues
let trimmedAtomicValue = atomicValue.Trim()
orderby trimmedAtomicValue
select trimmedAtomicValue).Distinct()
select new CheckedListBoxItem(value)).ToList();
e.CheckedComboBox.Items.Clear();
foreach (var atomicItem in distinctAtomicValues)
e.CheckedComboBox.Items.Add(atomicItem);
string filterString = e.Column.FilterInfo.FilterString;
if (!string.IsNullOrEmpty(filterString))
{
var filterItem = (CheckedColumnFilterPopup.RepositoryItemFilterComboBox)e.CheckedComboBox;
filterItem.FilterValues =
string.Join("\n",
from item in filterItem.Items.OfType<CheckedListBoxItem>()
let itemValue = (string)item.Value
where itemValue != null && filterString.Contains("Contains([" + e.Column.FieldName + "], '" + item.Value + "'")
select itemValue);
}
}

How to Edit/Update Data in Collection in C#

I have a collection in my C# code
private ObservableCollection<UserForms> _userForms =
new ObservableCollection<UserForms>();
public ObservableCollection<UserForms> UserForms { get { return _userForms; } }
I am filling collection with 4 values
foreach (DataRow dr in DataTable.Rows)
{
UserForms.Add(new UserForms()
{
FormID = Convert.ToInt32(dr["FormID"]),
FormName = dr["FormName"].ToString(),
FromSyName = dr["FormSyName"].ToString(),
Visibility = false,
RoleAdd=false,
RoleEdit=false,
RoleDelete=false
});
}
I am filling this in Form_Load() event
Now I want to update
Visibility = true,
RoleAdd=true,
RoleEdit=true,
RoleDelete=true
in specified row in the collection.
You simply need to do the following:
UserForms[0].Visibility = true;
where "[0]" is the index.
If your ObservableCollection is enumerable (which collections usually are) you can use a foreach loop as follows:
foreach(UserForms uf in UserForms)
{
if (uf.FormID > 10)
uf.Visibility = true;
}
In the above code, I change the visibility of rows which their FormID is higher than 10.
Looks like you need filter out some items and then update them.
foreach(UserForms uf in UserForms.Where(i=>i.FormName == "FormName"/*put your filtering criteria here*/))
{
uf.Visibility = true;
// Set all needed properties here
}
You want to access the instance of collection.
_userForms.ToList().ForEach((f) => f.Visibility = true);
or if you know the index and want to update individual item.
_userForms[index].Visibility = true;
or for multiple filter items
var filterColl = coll.Where((c)=> c.FormName.StartsWith("A"));
filterColl.ToList().ForEach((f) => f.Visibility = true);
hope this helps..

Categories

Resources