We are using Xamarin traditional approach & MVVM Cross.
We want to fire a method which is in the view from ViewModel. What is the best way to achieve it? Is it by IMvxInteraction or MessageCenter?
In another case, we want to fire a method in ViewModel from View. What is the best way to achieve it?
Thanks in advance.
ViewModel
{
func method1()
{
// Trigger a method in iOS View. Which is method2
}
}
iOSView
{
func method2()
{
// Trigger a method in ViewModel. Which is method1
}
}
You have to bind your view to a Command in your ViewModel. See how to use ICommand in https://www.mvvmcross.com/documentation/fundamentals/data-binding.
You may look at Method Binding as well https://www.mvvmcross.com/documentation/plugins/methodbinding.
Related
I have a problem which drives me nuts, how is it possible to invoke a function in a view controller from within a UITableViewCell. - I am doing that in Swift.
So I have a View Controller - called mainVC
in this mainVC I have declared a tableView which holds a UITableViewCell (Custom/ Dynamic) in that tableView cell I want call a function which is declared in the mainVC. If I do like self.superview?.myFunc doesn't work.
I hope someone can help me...
It is not as easy as that unfortunately.
What you want to look into is NSNotificationCenter or even better: - Delegates.
If you want a better understanding of Delegates I'd recommend this tutorial: http://www.raywenderlich.com/75289/swift-tutorial-part-3-tuples-protocols-delegates-table-views
If you don't want to read all that, I'll try my best to explain it here.
Let's say you have two view controllers: mainVC and otherVC.
Above the class definition in otherVC, add the following code:
protocol OtherVCDelegate {
func cellClicked()
}
Inside the class in otherVC, add the following property:
var delegate: OtherVCDelegate?
In the didSelectRow (or where you execute the code), add the following code:
self.delegate?.cellClicked()
Now, back in mainVC: Make mainVC conform to this delegate by adding it to the class like this:
class MainViewController: UIViewController, DetailDelegate {
}
In MainViewController add the delegate function and insite that one put your function you want to execute:
func cellClicked() {
println("Cell was clicked")
myFunc()
}
The last thing you have to do is make MainViewController the delegate of OtherViewController. This has to be done where you access the otherVC from the mainVC. Let's say it is done in prepareForSegue:
if segue.identifier == "showDetail" {
(segue.destinationViewController as DetailViewController).delegate = self
}
It is a little bit complicated at first, but once you get a grasp of it it's a walk in the park.
In my xaml page i am using an image control
<Image x:Name="MyImage" Grid.Row="1" Stretch="UniformToFill" Source="{Binding SourceImage}"/>
like this. My question is. Is it possible to access this control's properties in my view model. "Like MyImage.Source =". If yes, how i can achieve similar implementation in windows phone.
Yes, you can, but you should not. The whole purpose of the ViewModel is to separate the logic into its own class rather than having it intermixed with view code.
Instead use the INotifyPropertyChanged interface to notify the UI that the image source has changed. If possible try to see if you can use a regular binding for the value you want to use, that will be the most robust and most easy way.
Another solution is to expose a interface on the view. Something like IView, you can probably come up with a more suitable name like IResetable.
interface IResetable
{
void Reset();
}
class MainWindow: Window, IResetable
{
publiv void Reset()
{
// Here you can access the view, but try to keep logic minimal.
}
}
class ViewModel
{
private readonly IResetable resetable;
public ViewModel(IResetable resetable)
{
_resetable = resetable;
}
void Foobar()
{
_resetable.Reset();
}
}
I'm trying to bind CheckedChange from monodroid CheckBox to a command, but I get an error.
I want to unselect another item when a particular one is checked.
I think it is possible to do it with EventTrigger in wp7, but MvvmCross for android doesn't seem to support this feature.
Is MvvmCross limited to Button only ?
Thanks in advance for your help.
CheckedChanged is an EventHandler<CompoundButton.CheckedChangeEventArgs> so it isn't one of the delegate types that MvvmCross automatigically knows about.
However, there is a custom binding in place for this...
https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/Target/MvxCompoundButtonCheckedTargetBinding.cs
And this custom binding should be registered using:
registry.RegisterFactory(new MvxSimplePropertyInfoTargetBindingFactory(typeof(MvxCompoundButtonCheckedTargetBinding), typeof(CompoundButton), "Checked"));
in https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/MvxAndroidBindingBuilder.cs
So if you have a ViewModel with a property IsSpecial
private bool _isSpecial;
public bool IsSpecial
{
get { return _isSpecial; }
set
{
_isSpecial = value;
RaisePropertyChanged(() => IsSpecial);
// your custom code here
}
}
then this binding should work:
'Checked':{'Path':'IsSpecial'}
And that should work for any CompoundButton - CheckBox, Switch, or your own compounds...
I need to use ABPeoplePickerView to implement my AddressBook application. the view in IB is like this:
and it's like the following after running:
I want to delete the search field and add a button(like "add") on the top, but I don't know how to change the view layout. Is there any way to do it?
You can subclass the view to customize it.
This function finds the search field. Hopefully it may point the way for you to proceed.
extension ABPeoplePickerView {
func searchField () -> NSSearchField?{
for v in self.subviews[0].subviews {
if v.isKind(of: NSSearchField.self) { return (v as! NSSearchField) }
}
return nil
}
}
I have made a custom NSView and have implemented the keyDown: method. However, when I press keys the method is never called. Do I have to register to receive those events? fyi, I am making a document based application and can handle this code anywhere (doesn't have to be in this view). What is the best place to do this in a document based application such that the event will occur throughout the entire application?
You need to override -acceptsFirstResponder to return YES.
In Swift:
class MDView: NSView {
override var acceptsFirstResponder: Bool { return true }
}