Find textbox by name in a list of textboxes - c#

Given a list of RichTextBox, I would like to access one by its name.
So for example:
EDIT
I shouldn't have used the loop in the question. I am trying to access the name without a for loop.
public RichTextBox boxFinder(List<RichTextBox> boxes)
{
return boxes.Find("boxname")
}

The simplest method would be to use FirstOrDefalut
return boxes.FirstOrDefault(b => b.Name == "MyName");
First will throw if there is no matching element. Note that this essentially performs a foreach that breaks after an element is found under the hood.

Find is a function which takes a predicate (that is, a delegate which returns a bool). You can call find using lambda:
public RichTextBox boxFinder(List<RichTextBox> boxes)
{
return boxes.Find(box=>box.Name == "boxname");
}
Of course wrapping it in a function like this probably doesn't buy you much.

Related

using lambda expression to set combo box data source c# windows Forms application

given the following instance variable
cboBankAccountId.DataSource = db.BankAccounts.Where(x => x.BankAccountId).ToList();
Lets assume that my table names and properties are all correct... can somebody explain to me why this way of assigning a data source does not work with a windows form application.
However i seen in other posts that the following (and what i used in my project) works.
Now is this simply because of how a combo boxes properties are assigned in a windows form vs a web form??
cboBankAccountId = db.BankAccounts;
cboBankAccountId.ValueMember = "BankAccountId";
cboBankAccountId.DisplayMember = "FullName";
thanks...
and happy thanksgiving!
A ComboBox control's data source can be a database, a Web service, or an object that can later be used to generate data-bound controls.
The problem with your code is in your lambda expression.
The extension method "Where" in your case expects a delegate of type Func<BankAccounts, bool>. i.e., you must pass a delegate which takes BankAccounts as input and gives bool as output which is used to filter your result.
So, if you wanted to find out BankAccounts with an Id of 1, your lambda expression would look like this:
cboBankAccountId.DataSource = db.BankAccounts.Where(x => x.BankAccountId == 1).ToList();
If you are new to Lambda Expressions, you can also translate it as:
cboBankAccountId.DataSource = db.BankAccounts.Where((BankAccounts x) =>
{
return x.BankAccountId == 1;
}).ToList();
or, the full version:
public bool Filter(BankAccountId id)
{
bool filterPassed;
if(id == 1)
filterPassed = true;
else
filterPassed = false;
return filterPassed;
}
cboBankAccountId.DataSource = db.BankAccounts.Where(Filter).ToList();
As you can see, all you need to pass to the Where method is a method which can be used for filtering out the result. Each item in the list is then run through this method and only the ones that pass the test are returned. That's how the Where extension method in LINQ works.

Lambda expression does not work in object list

I have an object list and I can add record with that sentence:
List<DragerClass.Alarm> alarms = new List<DragerClass.Alarm>();
public void createAlarm(int i, int[] alarms)
{
alarms.Add(new DragerClass.Alarm(i, DateTime.Now, DragerClass.Dedector.Dedector_Name[i] + " UNDER RANGE"))`;
}
But when I try to remove an item, it behaves like lambda expression doesn't support:
public void removeAlarm(int i)
{
alarms.Remove(x => x.Dedector_No == i);
}
I see that message when I stand on the code
cannot convert lambda expression to type
'Drager_GasDedection.DragerClass.Alarm' because it is not a delegate
type
I'm using Visual Studio 2010 and I also added System.Data.Entity in references. But still same. Thanks for any help.
Take a look at the methods of List<T>. The method Remove(T) simply expects one element. If it is found in the list it is removed, otherwise nothing is done. Remove is not looking for a Predicate<T> that it will check.
RemoveAll(Predicate<T>) however expects a predicate. So you need to call:
alarms.RemoveAll(x => x.Dedector_No == i);
You also have to change = to == in your code since otherwise you are performing an assignment instead of an equality check. Furthermore note that the method will remove all alarms with the given detector number, not just the first.

How to declare var as global which stores value of controls?

I have two radio buttons in CriminalityInformationFormViewDisposal and I'm finding this controls dynamically as follows
var siaHasConvictions =
((RadioButtonList)CriminalityInformationFormViewDisposal.FindControl(ContactEntity.SIA_HASCOVICTIONS));
var siaHasOffencesAwatingTrial =
((RadioButtonList)CriminalityInformationFormViewTrial.FindControl(ContactEntity.SIA_HASOFFENCEAWAITINGTRIAL));
now on one page whenever I need to fetch the value of radio buttons i.e. whether it is selected or not every time I need to define var to find control first and then I check for its value...now it increases code line ..is there any way so I can make this findcontrol part global for that one page and then I access its value like we do for normal control ,please help me out for this,as I tried it to declare before page load,,,but gives error for gridcontrol
There is no easy way in my opinion, but this might help you not repeat the code over and over again:
private RadioButtonList SiaHasConvictions
{
get
{
return (RadioButtonList)CriminalityInformationFormViewDisposal.FindControl(ContactEntity.SIA_HASCOVICTIONS);
}
}
With this property, you can just use this.SiaHasConvictions in your code. You could optimize this by saving the reference once in a variable:
private RadioButtonList _siaHasConvictions;
private RadioButtonList SiaHasConvictions
{
get
{
if (this._siaHasConvictions == null)
{
this._siaHasConvictions = (RadioButtonList)CriminalityInformationFormViewDisposal.FindControl(ContactEntity.SIA_HASCOVICTIONS);
}
return this._siaHasConvictions;
}
}
Using the second piece of #Patrick Hofman's code is NOT guaranteed a correct behavior. If the FindControl method may return different values each time you call it, this implementation will go wrong since _siaHasConvictions won't get changed anymore once set.
However, I was inspired from #Patrick Hofman's idea of using property, you could use ?? operator in your Property to make things even easier:
private RadioButtonList _siaHasConvictions;
private RadioButtonList SiaHasConvictions
{
get { return this._siaHasConvictions ?? (this._siaHasConvictions = (RadioButtonList)CriminalityInformationFormViewDisposal.FindControl(ContactEntity.SIA_HASCOVICTIONS)); }
}
Here is the explanation and some examples of using ?? operator, and in short:
The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.

Return object from list of objects based on variable in C#

I have a list of objects, of class Author, and I want to search this list of authors, based on one of the Author's properties, name, and when I receive a match I would like to return the instance of Author to be used to create an instance of another class, that requires Author as part of its constructor.
A better way to explain it would be:
author getAuthor(String arg_name)
{
foreach (author auth in authorList)
{
if (auth.name == arg_name)
{
return auth;
}
}
}
Although I realize this specific code does work, is there a better way to perform this action?
You can use Enumerable.FirstOrDefault like:
return authorList.FirstOrDefault(a=> a.name == arg_name);
This would return null if any author with name doesn't matches with the parameter passed.
For your particular code, your check if (auth == arg_name) should give you compile time error. Your check should be if (auth.name == arg_name)
Assuming you have a public property of Name in the Author you should be able to to get its value and compare it to the requested value (in your case arg_name). One way is to use foreach:
foreach (author auth as authorList)
{
if (auth.name == arg_name)
{
return auth;
}
}
Another way is to use Linq:
return authorList.FirstOrDefault(r=> r.name == arg_name);
The LINQ solution, although compact and elegant, is inefficient. You could use a dictionary, mapping from name, to index inside the list. Take into account that this solution is inefficient in adding/removing items, especially if they're added/removed from the middle of that list.... Think about which solution is more appropriate for you

Using Lambda Expression on an ObservableCollection

in my Silverlight 4 application, I have an ObservableCollection which consists of objects of a class and is defined by an interface:
interface myInterface()
{
string Name { get; set; }
string Value { get; set; }
}
class myClass() : myInterface
{
...
}
ObservableCollection<myInterface> _collection;
Before adding a new element to the collection, I want to make sure, that the Name-Property does not already exists within the current collection elements.
As I cannot work with contains, I currently iterate through all elements and check each element manually.
private bool CollectionContainsElement(string name2CheckAgainst)
{
foreach (myInterface item in _collection)
if (item.Name.Equals(name2CheckAgainst))
return true;
return false;
}
I have read that this can also be achieved via a Lambda Expression, so I wrote the following:
if (!_collection.Contains(p => p.Name == name2CheckAgainst))
{
...
But now I get an error, saying that the "lambda expression could not be converted to the Type "myInterface", because it is no delegate-type". (Wording may differ, as I translated it from the german version)
I'm not sure what I have to change to make it work. using System.Linq; is included. And the second question (or maybe the primary question): I have read, that the runtime changes from O(1) for the Contains()-method to O(n) - which isn't faster than my current check. So does it even make sense to change it to using the lambda? And finally, is there probably another method in checking for an existing Name-Property in my class?
Thanks in advance,
Frank
You don't have to write a Contains method, the Any method of Linq is already doing that:
if (!_collection.Any(p => p.Name == name2CheckAgainst))
If you want to use a Lambda, you have to change the prototype of your Contains method to accept a Lambda (a lambda is just an alternative way to write an anonymous function):
private bool CollectionContainsElement(Func<myInterface, bool> lambda)
{
foreach (myInterface item in _collection)
if (lambda(item))
return true;
return false;
}
Using a lambda here doesn't change the complexity of your function, it's O(n) in both case. So it's just a matter of preference.
You can use the Linq Any() method. Which is useable like so:
if (!_collection.Any(p => p.Name == name2CheckAgainst))
{
}
The reason why the contains method is O(1) is that under the covers it loads your collection into a HashTable (or similar) and uses the hash code (followed by a call to Equals) to check whether an element is present.
Contains is not a LINQ extension and therefore you can't use lambda expressions with it. It was designed to check if provided object exists in the list.
As others have said, Any is a equivalent lambda-expression compatible extension method

Categories

Resources