I have an icon on my Xamarin.Forms app, which when it is clicked, I would like to change it to an activity indicator. It looks as though I should use a Trigger, Event Triggers look good, but as my image is declared in XAML, I am not sure quite how it would fit together?
At the moment, I have this in XAML at the bottom of a stacklayout
:
<Button x:Name="NewDeviceButton"
Image="glyphish_31_circle_x.png"
HorizontalOptions="End"
VerticalOptions="EndAndExpand" />
When it is clicked, I would like to show this, for a set amount of time, then trigger some C# functionality:
<ActivityIndicator Color="Black" IsRunning="true" />
I am not sure whether it would be best to configure it all in XAML with a trigger, or if i can just have a placeholder type item in XAML and then have all the definitions in C#?
There are a few ways of doing this.
You could simply give each of them an x:Name and then turn on/off IsRunning and IsVisible if you want to hide it.
I assume though that you have some data binding going on. Since IsRunning is a bool you could simply bind it to a boolean in your code behind. For instance In my ViewModel I have an IsBusy property and implement INotifyPropertyChanged:
public class MyViewModel : INotifyPropertyChanged
{
public MyViewModel()
{
}
private bool busy = false;
public bool IsBusy
{
get { return busy; }
set
{
if (busy == value)
return;
busy = value;
OnPropertyChanged("IsBusy");
}
}
public async Task GetMonkeysAsync()
{
if (IsBusy)
return;
try
{
IsBusy = true;
//do stuff here that is going to take a while
}
finally
{
IsBusy = false;
}
}
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
var changed = PropertyChanged;
if (changed == null)
return;
changed(this, new PropertyChangedEventArgs(name));
}
#endregion
}
Then in the XAML you can bind to IsBusy:
<ActivityIndicator IsRunning="{Binding IsBusy}"
Color="Blue"/>
I think that should handle it. If you need a timer you could use the same binding that I have here and use Xamarin.Forms built in timer class.
James' answer is correct, however, I prefer to use the page's own IsBusy
property, for two reasons:
INotifyPropertyChanged
implementation if I don't have toThe only difference with James' answer (besides deleting the INPC implementation) is that you need to give the page a name (x:Name="myPage"
) and then declare the binding using a reference to it using {Binding Source={x:Reference myPage}, Path=IsBusy}
for the ActivityIndicator's IsVisible
and IsRunning
values.
i.e.:
MainPage.xaml:
<ContentPage ... x:Name="myPage">
...
<ActivityIndicator IsVisible="{Binding Source={x:Reference myPage}, Path=IsBusy}" IsRunning="{Binding Source={x:Reference myPage}, Path=IsBusy}" />
...
</ContentPage>
MainPage.xaml.cs:
...
async void OnDoSomethingLong(...)
{
if (!this.IsBusy)
{
try
{
this.IsBusy = true;
//await long operation here, i.e.:
await Task.Run(() => {/*your long code*/});
}
finally
{
this.IsBusy = false;
}
}
}
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With