Reputation:
I am trying to show an ImageButton
and pass it with Binding the source of the image and that when I click the button, make a command and go to a web page that I want
Im trying to do it with MVVM
and send the data to the ImageButton
from the ViewModel
MainPage.xaml:
MainPage.xaml.cs:
namespace BindingPrueba
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
}
ViewModel.cs:
namespace BindingPrueba
{
public class ViewModel
{
public string ImageSource { get; set; }
public string Website { get; set; }
public ViewModel()
{ }
public void launcWeb(string websiteUrl)
{
websiteUrl = "facebook.com";
Device.OpenUri(new Uri(websiteUrl));
}
}
}
Upvotes: 0
Views: 618
Reputation: 3751
To start with I would highly recommend that you add in an x:DataType
element to your top level ContentPage
see here for further detail. This should give multiple benefits but the key one I find is the IDE is able to identify if the property you are trying to bind to actually exists.
Your example should look something like:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="cir-namespace:BindingPrueba"
x:Class="BindingPrueba.MainPage"
x:DataType="local:ViewModel">
Next the key part is you will want implement INotifyPropertyChanged
so that any changes in your ViewModel
class will update the UI. Further details.
public ViewModel()
{
ImageSource = ImageSource.FromFile("my path to file");
}
Hopefully now if you followed step 0 then the IDE should make it clear that you don't have an OpenAppCommand
defined on your ViewModel
. If you add this then you should be able to trigger the action in your class.
e.g. (inside ViewModel
)
public Command OpenAppCommand { get; }
public ViewModel()
{
OpenAppCommand = new Command(() => Device.OpenUri(new Uri(this.Website)));
}
Note you don't strictly need to implement INotifyPropertyChanged
if only updating in the constructor but it is good practise to.
Upvotes: 0
Reputation: 3986
Add the command property to your viewmodel:
public class ViewModel
{
public string ImageSource { get; set; }
public string Website { get; set; }
public Command OpenAppCommand { get; set; }
public ViewModel()
{
OpenAppCommand = new Command(launcWeb);
}
public void launcWeb()
{
var websiteUrl = "facebook.com";
Device.OpenUri(new Uri(websiteUrl));
}
}
If you want to pass the CommandParameter
to the command to use your lanchWeb(string websiteUrl)
do something like this instead:
public class ViewModel
{
public string ImageSource { get; set; }
public string Website { get; set; }
public Command<string> OpenAppCommand { get; set; }
public ViewModel()
{
OpenAppCommand = new Command<string>(launcWeb);
}
public void launcWeb(string websiteUrl)
{
websiteUrl = "facebook.com";
Device.OpenUri(new Uri(websiteUrl));
}
}
The CommandParameter
can be set from your xaml
.
Upvotes: 1
Reputation: 454
How about that? Instead of using an ImageButton use a Frame containing an Image with a GestureRecognizer.
<Frame Style="{DynamicResource FrameButton}">
<Image Source="{Binding SomeSource}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding CommandFromVM}"
CommandParameter="{Binding SomeSource}"/>
</Image.GestureRecognizers>
</Image>
</Frame>
Or just use the ImageButton and use the CommandParameter
Property
Upvotes: 0