Using PerformSelector with #selector in MonoTouch - c#

I am trying to convert the following iOS code into MonoTouch and cannot figure out the proper conversion for the #selector(removebar) code. Can anyone provide guidance about the best way to handle #selector (since I've come across that in other places as well):
- (void)keyboardWillShow:(NSNotification *)note {
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
}
My C# code is:
NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification,
notify => this.PerformSelector(...stuck...);
I am basically trying to hide the Prev/Next buttons that show on the keyboard.
Thanks in advance for any help.

NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, removeBar);
where removeBar is a method defined elsewhere.
void removeBar (NSNotification notification)
{
//Do whatever you want here
}
Or, if you prefer using a lambda:
NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.WillShowNotification,
notify => {
/* Do your stuffs here */
});

Stephane shows one way you can use our improved bindings to convert that.
Let me share an even better one. What you are looking for is a keyboard notification, which we conveniently provide strong types for, and will make your life a lot easier:
http://iosapi.xamarin.com/?link=M%3aMonoTouch.UIKit.UIKeyboard%2bNotifications.ObserveWillShow
It contains a full sample that shows you how to access the strongly typed data that is provided for your notification as well.

You have to take into account that:
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
it's exactly the same that
[self removeBar];
The call to performSelector is just a method call using reflection. So what you really need to translate to C# is this code:
- (void)keyboardWillShow:(NSNotification *)note {
[self removeBar];
}
And I guess that also the notification subscription, that sums up to this code:
protected virtual void RegisterForKeyboardNotifications()
{
NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, OnKeyboardNotification);
NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, OnKeyboardNotification);
}
private void OnKeyboardNotification (NSNotification notification)
{
var keyboardVisible = notification.Name == UIKeyboard.WillShowNotification;
if (keyboardVisible)
{
// Hide the bar
}
else
{
// Show the bar again
}
}
You usually want to call RegisterForKeyboardNotifications on ViewDidLoad.
Cheers!

Related

Call an Activity method from Fragment

I'm using ToDoActiviy.cs for user login, this class got this method:
[Java.Interop.Export()]
public async void LoginUser(View view)
{
if(await authenticate())..
This method is called from .axml file from Button widget android:onClick="LoginUser" I changed this for android:onClick="LoginUserClick" This last method create a dialog fragment for show different logins accounts.
Now from the Dialog Fragment(Is situated on another class) I want to hand the event for the button click on the dialog fragment and call this method from ToDoActivity.cs.
On dialog fragment class I hand the click event like this:
private void ButtonSignInFacebook_Click(object sender, EventArgs args){
//Here code for call to LoginUser method from 'ToDoActivity.cs'
ToDoActiviy.cs act = new ToDoActivity();
act.LoginUser();
}
I need to pass a View but I tried a lot of things and any works..
Someone can help me?
Thanks in advance ;)
I would like to make a slight modification to #guido-gabriel 's answer.
In C# syntax, it will be
((ToDoActivity)Activity).yourPublicMethod();
Getter/Setter Methods in Java are mapped to Getter Setter properties in Xamarin.Android
Finally I fix it ! I had to change the parameters of the method and create it without parameters.. and now Is working. Both solutions are good:
((ToDoActivity)Activity).LoginUserFacebook();
//ToDoActivity act = new ToDoActivity();
//act.LoginUserFacebook();
Adapt and use the snipped below in your fragment
var casted = Activity as MyActivityName;
if (casted != null) {
casted.IWantToCallThisMethodFromMyFragment();
}
You have to call the method from the activity. Have you tried?
((YourActivityClassName)getActivity()).yourPublicMethod();
I.E.
((ToDoActivity)getActivity()).yourPublicMethod();
This is not really a good practice to do. Why?
Doing this couples the Fragment tightly to this particular Activity type, meaning it will not be possible to reuse the Fragment elsewhere in the code.
Instead I suggest you rely on the Activity subscribing to an event or implementing some kind of callback method in order to do the desired action after login.
It could also seem like your Activity might be containing a lot of logic that could be split out into a shared library of some kind. Making it possible to reuse that code on another platform, for instance iOS in the future.
So since your are in charge of newing up the Fragment, I would do something like this instead:
public class LoginFragment : Fragment
{
Action _onLoggedIn;
public static void NewInstance(Action onLoggedIn)
{
var fragment = new LoginFragment();
fragment._onLoggedIn = onLoggedIn;
return fragment;
}
private void Login()
{
// login user
// after loggedin
_onLoggedIn?.Invoke();
}
}
Then in your Activity:
private void LoginUser()
{
// whatever
}
var loginFragment = LoginFragment.NewInstance(LoginUser);
// fragment transaction here...

WPF validation of input (on-the-fly) and unit test. Best practice for design

I want to add a new form to an existing solution. The solution already has a Validator class, so I want to expand this class.
The Form I want to create contains a Textbox (for the input) and a Button. When the input is the correct format the submit button is enabled. The input must adhere to a certain regular expression: "^[A-Za-z]{2}[0-9]{5}$". I'm checking the input (on-the-fly) in the Form class like this:
private void inputTbx_TextChanged(object sender, TextChangedEventArgs e)
{
SubmitButton.IsEnabled = Validator.IsInputValid(inputTbx.Text, RegexExpression);
}
I've put the regular expression as a variable in the Form class. I put it here because it is relevant to the textbox of this form only.
private const string RegexExpression = "^[A-Za-z]{2}[0-9]{5}$";
Here's the validation code:
public static bool IsInputValid(string inputToBeChecked, string regexExpression)
{
if (inputToBeChecked == null || regexExpression == null)
{
return false;
}
var regex = new Regex(regexExpression, RegexOptions.None);
return regex.IsMatch(inputToBeChecked);
}
So far so good. It seems to work fine. But I want to unit test it like so:
[TestCase("aZ13579")]
public void ValidateInputOkTest(string input)
{
Assert.IsTrue(Validator.IsInputValid(input, RegexExpression));
}
But to do it like this I have to have a string in my ValidatorTest class similar to the Regular-expression used in the Form class. This doesn't seem like the right way to do it. What I really want to do is get the Regex expression from the form class, so I am sure it's the correct Regex-expression that I'm using. Otherwise the Regex-expressions could easily get out of sync.
Here are the questions:
What is best practice here?
How do I get to this expression? I've tried doing it using Reflection, but I get a Threadstat error because it's a GUI component. Should I move the Regular-expression? If so where to?
I'm thinking there must be a smart way to do this. A smart design perhaps. Suggestions and comments are welcome.
You're probably going to want to back up a step and start to research the 'MVVM' design pattern. When you hear people talk about putting no code in the code behind, testing like this is one of the big benefits (among many others).
MVVM is too big a topic to handle in a simple answer like this. I'd search around on the web, and I'm sure other people have some good tutorials.
Just to be clear, it can be a big learning curve, but it's totally worth it. MVVM is what makes WPF much much (MUCH) better than WinForms, rather than merely different.
Just to address your question a little more specifically, you won't be testing a GUI object like a Window or UserControl. You'll be testing a view model which is just a regular class.
Here's a simplified version of what you might see
public class MyScreenViewModel : INotifyPropertyChanged
{
private const string RegexExpression = "^[A-Za-z]{2}[0-9]{5}$";
public bool UserInputIsValid { get { stuff; } set { stuff; }}
public string UserInput { get { stuff; } set { stuff; ValidateUserInput();} }
private void ValidateUserInput()
{
if (UserInput == null)
{
return false;
}
var regex = new Regex(RegexExpression, RegexOptions.None);
UserInputIsValid = regex.IsMatch(UserInput);
}
}
A view model in MVVM is the real logic of your screen. It will expose simple properties that the view can bind to for display/input, but the view isn't necessary for testing the logic.
Then your test looks something like:
[TestCase("aZ13579")]
public void ValidateInputOkTest()
{
var vm = new MyScreenViewModel();
vm.UserInput = "SomeValidText";
Assert.IsTrue(vm.UserInputIsValid);
}
[TestCase("aZ13580")]
public void ValidateInputNotOkTest()
{
var vm = new MyScreenViewModel();
vm.UserInput = "SomeInvalidText";
Assert.IsFalse(vm.UserInputIsValid);
}

Checking for a condition in the calling scope or inside the function

i have the following 3 examples which does the same thing
//case1 do it if the condition is valid
private void SetMultiplePropertyValues()
{
if (Keyboard.GetKeyStates(Key.CapsLock) == KeyStates.Toggled)
{
//do somthing
}
}
//case 2 return if the condition is not valid
private void SetMultiplePropertyValues()
{
if (Keyboard.GetKeyStates(Key.CapsLock) != KeyStates.Toggled) return;
//do somthing
}
//case 3 checking the condition in the calling scope
if (Keyboard.GetKeyStates(Key.CapsLock)== KeyStates.Toggled)
SetMultiplePropertyValues())
private void SetMultiplePropertyValues()
{
//do somthing
}
which one would you go with and why
They do not do the same thing because in the first two cases the name of the method is a lie; the method name should be SetValuesIfTheKeyStateIsToggled or TryToSetValues or some such thing. Don't say you're going to do a thing and then not do it. More generally: separate your concerns. I would choose a fourth option:
public void TryToFrob()
{
if (CanFrob()) DoFrob();
}
private bool CanFrob()
{
return Keyboard.GetKeyStates(Key.CapsLock) == KeyStates.Toggled;
}
private void DoFrob()
{
// frob!
}
Notice what is public and what is private.
This is a silly looking example because each one is so simple, but one can easily imagine a situation in which these methods are complex. Keep your policies and your mechanisms logically separated. The mechanism is "is the keyboard in a particular state?" The policy is "I have some conditions under which I can frob; we must never frob unless those conditions are met".
First of all, as we can see at code comments, they don't do the same thing. So I think that you're talking about code architecture rather than functionality.
Second, here in SO isn't about giving opinions, but I'll try say to you concrete things about these differences.
1- Common if approach
if (true == false)
{
return true;
}
vs.
2 - Single line if approach
if (true == false) return true;
Most of code convetions says to use the option 1, because they're easier to read and understant code, and avoid some mistakes. We need to also understand that convetions are not rules! so they're just convetions, but really try to avoid option 2 in most of the cases.
One more thing, some code convetions also says that's ok using option 2 when you need something very simple, like this given example which is really easy to read and understand. But take this like an exception from the 'rules'.

EntityCollection as parameter in a method

I am trying to write a code where EntityCollection is the parameter of the method
but I don't know what is the proper coding
is there someone who can help me about this?
here is the sample code
//by the way, this is a wrong coding, I am just showing you, what is the thing that I want to do...
private void sampleMethod(EntityCollection a)
{
if (a.ToList().Count == 0)
{
//body
}
}
and when I call it, this is what it looks like
sampleMethod(employee.EducationalBackground);
The question is a little difficult to understand but I suppose you're looking for something like this:
private void sampleMethod(EntityCollection<Employee> employees)
{
foreach(var employee in employees)
{
// do something with every employee.EducationalBackground
}
}
Search for "c# Generics" for info about the EntityCollection<Employee>.
Search for "linq" for info about how to work with collections.

Single reusable function to open a single instance of form

I am trying to create a reusable function that can open a single instance of form. Means if a form is not already open it should create and show the new form and if already open it should bring the existing form to front.
I was using the following function,
if (Application.OpenForms["FPSStorageDemo"] == null)
{
FPSStorageDemo fp = new FPSStorageDemo();
fp.Name = "FPSStorageDemo";
fp.Show();
}
else
{
((FPSStorageDemo)Application.OpenForms["FPSStorageDemo"]).BringToFront();
}
But I have to write this code again and again whereever I have to open a form. But I need a single reusable function that can do this job.
I wrote a function like,
void OpenSingleInstanceForm(Type TypeOfControlToOpen)
{
bool IsFormOpen = false;
foreach (Form fm in Application.OpenForms)
{
if (fm.GetType() == TypeOfControlToOpen)
{
IsFormOpen = true;
fm.BringToFront();
break;
}
}
if (!IsFormOpen)
{
Object obj = Activator.CreateInstance(TypeOfControlToOpen);
//obj.Show(); //Here is the problem
}
}
But at the end I don't know how to show the new form instance. Can anybody suggest how to do it? Is this wrong or there is another way to do this?
Thanks in advance.
public static class FormUtility
{
public static FormType GetInstance<FormType>() where FormType : Form, new()
{
FormType output = Application.OpenForms.OfType<FormType>().FirstOrDefault();
if(output == null)
{
output = new FormType();
}
//you could add the show/bring to front here if you wanted to, or have the more general method
//that just gives a form that you can do whatever you want with (or have one of each).
return output;
}
}
//elsewhere
FormUtility.GetInstance<Form1>.BringToFront();
I'd also like to take the time to mention that while having methods like this are quick and easy to use, in most cases they are not good design. It leads you to the practice of just accessing forms globally rather than ensuring that when forms need to communicate with each other they do so by exposing the appropriate information through the appropriate scope. It makes programs easier to maintain, understand, extend, increases reusability, etc. If you have trouble determining how best for two or more forms to communicate without resorting to public static references to your forms (which is exactly what Application.OpenForms is) then you should feel free to post that question here for us to help you solve.
You are looking for Singleton
Check this Implementing Singleton in C#

Categories

Resources