I want to do something like Google does in its search: if the user write some special char, like - or * the results are filtered.
What I have now: a filter that filters objects Name property with Contains method, and two special characters:
for leaving only the names that don't contain the typed text -
for searching a different property of my object (in my case it is Units) *
Ok, what I need is to combine above logic and be able to first filter with "-" or "*" and then be able to type and continue filtering the remaining results.
It's all about the logic I think, but it's getting complicated and I might need a little help.
item.View.Filter = delegate(object o)
{
//Lógica de filtrado
if ((item.FilterText.Length > 0) && ((item.FilterText[0] == '*') || (item.FilterText[0] == '-')))
{
//If the first char is *
if ((item.FilterText[0] == '*')
&& (((MyObject)o).Units[0].ToString().ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture).Substring(1))
|| ((MyObject)o).Units[1].ToString().ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture).Substring(1))))
{
return true;
}
//If the first char is -
if ((item.FilterText[0] == '-')
&& (!((MyObject)o).Name.ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture).Substring(1))
|| !((MyObject)o).Name.ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture).Substring(1))))
{
return true;
}
}
else
{
if (((MyObject)o).Name.ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture)))
{
return true;
}
}
return false;
};
Related
Recently I've been trying to create a method to make sure a string has certain types of chars. Yet when I tried using the method, it stops checking if the chars are that way on the 4th character.
For example I tried using 4 lowercase letters and it tells me it's false, but when I try to use invalid characters (lowercase, symbols) on the 5th character, it says it's true:
public bool CarLicensePlateCheck(string m)
{
if (m.Length >= 4 && m.Length <= 12)
{
foreach(char c in m)
{
if (char.IsDigit(c) == true || char.IsUpper(c)==true || char.IsWhiteSpace(c)==true || c.Equals("-"))
return true;
else
break;
}
return false;
}
else
return false;
}
You can try regular expressions and let .Net perform check for you:
using System.Text.RegularExpressions;
...
public static bool CarLicensePlateCheck(string m) =>
m != null && Regex.IsMatch(m, #"^[A-Z0-9\s\-]{4,12}$");
the pattern is
^ - start of the string
[A-Z0-9\s\-]{4,12} - from 4 to 12 characters which are either
in A..Z range - upper case letters
in 0..9 range - digits
\s - white space
\- - dash
$ - end of the string
You need to check if the character is not valid and return false immediately and then return true outside of the foreach (because at that point you've validated all the characters). What you have stops validating after the first character because if the first character is valid it just returns true and if it isn't it breaks from the foreach and returns false.
public bool CarLicensePlateCheck(string m)
{
if (m.Length >= 4 && m.Length <= 12)
{
foreach(char c in m)
{
// If it's not a valid character return false
if (!char.IsDigit(c)
&& !char.IsUpper(c)
&& !char.IsWhiteSpace(c)
&& c != '-')
return false;
}
// all characters have been validated so return true
return true;
}
else
return false;
}
As the code is written now, it only checks the first character. If this character is valid CarLicensePlateCheck returns true. If it is invalid, the loop is broken and CarLicensePlateCheck returns false.
Check instead that the character is invalid and return false immediately, if so. Return true when the whole loop has passed.
Another option to those presented in the other answers is to use LINQ. This results in code that is very short and I think makes the intent very clear.
using System.Linq;
...
public static bool IsValid(char c)
{
return char.IsDigit(c) || char.IsUpper(c) || char.IsWhiteSpace(c) || c == '-';
}
public static bool CarLicensePlateCheck(string m)
{
return m.Length >= 4 && m.Length <= 12 && m.All(c => IsValid(c));
}
This code make use of LINQ's All method, which returns true if a predicate returns true for all elements of a sequence. I also added the static modifier to flag that these methods no not rely on any member variables or properties of the containing class.
Since each function is essentially a single expression this can be rewritten as:
public static bool IsValid(char c) =>
char.IsDigit(c) || char.IsUpper(c) || char.IsWhiteSpace(c) || c == '-';
public static bool CarLicensePlateCheck(string m) =>
m.Length >= 4 && m.Length <= 12 && m.All(IsValid);
It's a matter of taste which of these you prefer.
I have the two following pieces of code, in one I initialize the isSpclChar bool as false, in the other one I catch the false state later in an else statement:
static bool CheckSpclChar(char _letter)
{
bool isSpclChar = false;
if(_letter == '!' || _letter == '#')
{
isSpclChar = true;
}
return isSpclChar;
}
And:
static bool CheckSpclChar(char _letter)
{
bool isSpclChar;
if(_letter == '!' || _letter == '#')
{
isSpclChar = true;
}
else
{
isSpclChar = false;
}
return isSpclChar;
}
Which of them is best practice or less prone to errors in this type of case?
Does it not matter at all?
No need for an else at all:
bool isSpecialChar = _letter == '!' || _letter == '#';
In fact, your whole method can be simplified to:
static bool CheckSpecialChar(char letter) => letter == '!' || letter == '#';
I've expanded "Spcl" to "Special" for better readability, and removed the leading prefix from the parameter name to follow .NET conventions. You might also want to consider using Is instead of Check.
Finally, you might want to avoid using the word "special" in the method name too. I tend to wince when I hear the phrase "special character" because without more specific context, it's meaningless. What do ! and # mean in this context? Is there a more useful description you could give, such as IsEscapePrefix or something similar?
We should use variables when we need to use that values, otherwise you just need to write your method as follows. Let me know, if that makes sense?
static bool CheckSpclChar(char _letter)
{
if(_letter == '!' || _letter == '#')
{
return true;
}
return false;
}
I want to design a function that checks whether Player A or B wins.
Right now I'm just reusing a bunch of code. I would like to use the same function for each if possible. Right now I have two different if statements, one for A and for B. Any tips on how I should merge them?
Can I create a function which takes in both A and B values and use some kind of tenary function with just one if statement?
if (label[x,0].theValue() == A && label[x,1].theValue() == A && label[x,2].theValue) == A)
{
MessageBox.Show("A Wins!");
}
if (label[x,0].theValue() == B && label[x,1].theValue() == B && label[x,2].theValue) == B)
{
MessageBox.Show("B wins!");
}
I think you can do something like this:
public string CheckWinner(int x){
if( "your code" ) { return "A wins"; }
if( "your code" ) { return "B wins"; }
}
And then on your main function (form)
MessageBox.Show(CheckWinner(1));
I Hope this helps.
You can write a funktion to check if a given player has won like this (assuming A and B in your code are Player-objects)
private bool HasWon(Player player)
{
if (label[x,0].theValue() == player && label[x,1].theValue() == player && label[x,2].theValue() == player)
{
return true;
}
return false;
}
You can use this function like so:
if(HasWon(A))
{
MessageBox.Show("A Wins!");
}
or, if you have a List or something like this of all playing players, do like so:
foreach(var player in players)
{
if(HasWon(player))
{
MessageBox.Show(player.Name + " Wins!");
}
}
Add a method to check if A is the winner:
public bool IsAWinner(string x0value, string x1value, string x2value)
{
if (x0value == "A" && x1value == "A" && x2value == "A")
return true;
return false;
}
Call this one from your UI code to check if A is the winner, if it isn't, B is the winner.
The idea is to NOT use windows controls in this method; so that it can be tested (loose coupling from UI).
So from your UI:
if (IsAWinner(label[x,0].theValue(), label[x,1].theValue(),label[x,2].theValue))
MessageBox.Show("A Wins!");
else
MessageBox.Show("B wins!");
Also, don't forget to add some exception handling.
While I've never used C# I would imagine the second If statement is not needed. If A wins, then B loses whereas if B Wins A loses.
If A wins ... else B wins!
Sorry I can't give you a code sample, C# isn't my thing.
i have a project in which i have assigned some functions to single characters(e.g. Keyboard Key "H" will do high pass filtering).
Now To get "H" as an output i have created a down event which hopefully pick up the keys are down and calls the function with an integer value. However I get an error when i try to compare the input value with an integer value in the function. The following is my code...
public static event DownEventHandler Down;
public static delegate void DownEventHandler(string Key);
Down(FunctionChar((Keys)lParam.Code)); // lParam.code is an integer value.
private string FunctionChar(Keys e)
{
if(e >=65 && e<=90){
if (Control.IsKeyLocked(Keys.CapsLock) || ((Control.ModifierKeys !=0) && (Keys.Shift) != 0))
{
return e.ToString;
}
else
{
return e.ToString.ToLower;
}
}
I assume that this function will give me the output a string either "G" or "g". as mentioned before i want to use it in further functionality.
However it gives me error as following.
Operator '>=' cannot be applied to operands of type 'System.Windows.Forms.Keys' and 'int'
I know one of the solution is to use SWITCH statement but i want to use if statement and not switch.
Can some one tell me - what is the problem? What values does "e" posses and how can i convert it to (Int) so i can use it in the IF statement.
You can't compare System.Windows.Forms.Key with and Integer so you have to convert the key has been converted to an integer before you compare them. here is an example for you:
Keys e = Keys.A;
int keyVal= (int)e;// return 65
So you can do like this:
if((int)e >=65 && (int)e<=90)
{
// your code goes here
}
Another way for doing this is:
if(e >= Keys.A&& e<= Keys.Z)
{
// your code goes here
}
Update :
You can return the corresponding character using : return ((char)e).ToString();
Hence the whole function signature will be like the following:
private string FunctionChar(Keys e)
{
if ((int)e >= 65 && (int)e <= 90)
{
if (Control.IsKeyLocked(Keys.CapsLock) || ((Control.ModifierKeys != 0) && (Keys.Shift) != 0))
{
return ((char)e).ToString();
}
else
{
return ((char)e).ToString().ToLower();
}
}
return "";
}
When working with an enum, such as Keys, it's better design to express any conditions in terms of the enum's values, rather than casting back to ints.
So I'd recommend replacing:
if(e >=65 && e<=90)
with
if (e >= Keys.A && e <= Keys.Z).
This should compile fine - and your intention is clearer to anyone reading your code!
I'd rather not use magic numbers but actual chacraters, and I'd write an extension method(s) for this:
public static class KeysExtensions
{
public static Boolean IsLetter(this Keys value)
{
return value >= Keys.A && value <= Keys.Z;
}
}
So when handling events you can put readable code:
private void Something_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.IsLetter())
{
// Do your operations here...
}
}
I want to check whether a given path is an explicit path that unambiguously specifies a particular location. So, I want to rule out paths like:
file
directory
directory\file
C:file
\directory\file
I want to allow:
C:\file
C:\directory
C:\directory\file
\\server\share\file
\\server\share\directory\file
The Path.IsRooted method almost does what I need, but it returns true for the last two examples above (C:file and \directory\file), which respectively imply a current directory and current drive.
Is there another method I can use? Note that I don't care whether the file/directory actually exists.
Use Path.GetFullPath() and compare the result to the original string:
bool IsPathAbsolute(string path)
{
return Path.GetFullPath(path) == path;
}
Digging into source code one can find the actual implementation of Path.IsPathRooted to be like this:
public static bool IsPathRooted(string path)
{
if (path != null)
{
Path.CheckInvalidPathChars(path);
int length = path.Length;
if ((length >= 1 && (path[0] == Path.DirectorySeparatorChar || path[0] == Path.AltDirectorySeparatorChar))
|| (length >= 2 && path[1] == Path.VolumeSeparatorChar))
{
return true;
}
}
return false;
}
Now it becomes evident how to adjust it to suit your needs - you can define a new method and slightly change the conditions (and maybe refactor them a little - they do not look very good):
if ((length >= 1 && ((path[0] == Path.DirectorySeparatorChar && path[1] == Path.DirectorySeparatorChar) || path[0] == Path.AltDirectorySeparatorChar))
|| (length >= 3 && path[1] == Path.VolumeSeparatorChar && path[2] == Path.DirectorySeparatorChar))