Reputation: 547
I'm building a Xamarin.Forms mobile app that will play an audio file while the user is using the app. The user will be able to continue to use the app after starting to play a file, and the file will be played/managed via a static class, rather than a single view (since that view may be removed from the navigation stack while the file is still being played).
I want to have a mini-player that is visible on any other view within the app, and I'm using a ControlTemplate to accomplish this. I want this control template to have some items that are bound to properties within the static class (such as player state [playing/paused], time remaining, title, etc.) as well as to have control to run methods upon the static class. I can run methods using code behind in my app.xaml page (where the ControlTemplate lives), but I'm having a hard time getting my bindable properties bound.
Right now I just have a toggle where IsToggled is supposed to bound to a bindable property IsPlaying is bound to the static class' bindable property.
I continue to get the error below:
Xamarin.Forms.Xaml.XamlParseException: Type AudioPlayer.Current not found in
xmlns clr-namespace:AudioPlayerBar;assembly=AudioPlayerBar...
I have defined the namespace in the XMLNS in all my .xaml so I'm not sure what's going on. My entire project is on GitHub at https://github.com/ChetCromer/XamarinPrototypes/tree/master/AudioPlayerBar
Here is my static class:
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace AudioPlayerBar
{
public class AudioPlayer :INotifyPropertyChanged
{
// Singleton for use throughout the app
public static AudioPlayer Current = new AudioPlayer();
//Don't allow creation of the class elsewhere in the app.
private AudioPlayer()
{
}
private bool _IsPlaying = false;
//property for whether a file is being played or not
public bool IsPlaying
{
get
{
return _IsPlaying;
}
set
{
_IsPlaying = value;
OnPropertyChanged("IsPlaying");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
And here's my ControlTemplate (inside app.xaml)
<ControlTemplate x:Key="PlayerPageTemplate">
<StackLayout VerticalOptions="FillAndExpand">
<ContentView VerticalOptions="FillAndExpand">
<ContentPresenter />
</ContentView>
<StackLayout x:Name="stackFooterContent">
<Label Text="IsPlaying Value:"/>
<Switch IsToggled="{x:Static local:AudioPlayer.Current.IsPlaying}" />
<Button Text="Toggle IsPlaying" Clicked="Click_PlayPause" />
</StackLayout>
</StackLayout>
</ControlTemplate>
Any thoughts? I'll admit I'm new to binding within Xamarin, but all that I'm reading seems to apply more to ContentPages and appears that it works differently with ControlTemplates.
Upvotes: 3
Views: 1736
Reputation: 547
I got this working using the examples here: Binding to a property within a static class instance
It's not quite the same issue so I'm leaving my question and answering it.
I did change my class to match the answer above, but the big change is how the binding code looks in xaml:
//New 2 way bindable property I made up
<Label Text="{Binding Source={x:Static local:AudioPlayer.Instance},Path=Title}"/>
//Boolean bindable property
<Switch IsToggled="{Binding Source={x:Static local:AudioPlayer.Instance},Path=IsPlaying}" />
The "Path" seems to be the big difference. Guess I'll be reading up on this some more as it just now popped up.
Upvotes: 3