Jump back in the Camera
project and let's begin adding a new folder called Controls
. Add in a new file called OrientationPage.cs
and implement the following:
public class OrientationPage : ContentPage { #region Static Properties public static Orientation PageOrientation; public static event EventHandler<Orientation> OrientationHandler; public static event EventHandler<Point> TouchHandler; #endregion #region Static Methods public static void NotifyOrientationChange(Orientation orientation) { if (OrientationHandler != null) { OrientationHandler (null, orientation); } } public static void NotifyTouch(Point touchPoint) { if (TouchHandler != null) { TouchHandler(null, touchPoint); } } #endregion }
In our previous chapter, we created an ExtendedContentPage
for handling alerts. This time, the ExtendedContentPage
will inherit the OrientationPage
, meaning it will be handling orientation events as well. The CameraPage
is going to use this OrientationPage
to track orientation events to resize camera preview areas, and rotate the camera view.
Our next control is the FocusView
. It is going to be used for custom rendering purposes so that we are able to record touch point (x, y) coordinates on a view plane. These touch points will then be used to focus the camera at that particular (x, y) coordinate.
Our next custom control is an extension to the Image
class. Add another file into the Controls
folder called CustomImage.cs
and implement the following:
public class CustomImage : View { public static readonly BindableProperty TintColorStringProperty = BindableProperty.Create ((CustomImage o) => o.TintColorString, string.Empty, propertyChanged: (bindable, oldvalue, newValue) => { var eh = ((CustomImage)bindable).CustomPropertyChanged; if (eh != null) { eh (bindable, TintColorStringProperty.PropertyName); } }); public string TintColorString { get { return (string)GetValue(TintColorStringProperty); } set { this.SetValue(TintColorStringProperty, value); } } public static readonly BindableProperty TintOnProperty = BindableProperty.Create ((CustomImage o) => o.TintOn, default(bool), propertyChanged: (bindable, oldvalue, newValue) => { var eh = ((CustomImage)bindable).CustomPropertyChanged; if (eh != null) { eh (bindable, TintOnProperty.PropertyName); } }); public bool TintOn { get { return (bool)GetValue (TintOnProperty); } set { SetValue (TintOnProperty, value); } } }
These custom bindings will be used for tinting. Since this view will be used for a CustomRenderer
, we will have access to native tinting features. This is where we will add some advanced techniques to our CustomRenderer
.
Next, we are going to add two more custom bindings. The Path
property will be used for the absolute path of the file, and the Aspect
property will be used for the image aspect ratio so we can change the image aspect natively:
public static readonly BindableProperty PathProperty = BindableProperty.Create((CustomImage o) => o.Path, default(string), propertyChanged: (bindable, oldvalue, newValue) => { var eh = ((CustomImage)bindable).CustomPropertyChanged; if (eh != null) { eh (bindable, PathProperty.PropertyName); } }); public string Path { get { return (string)GetValue(PathProperty); } set { SetValue(PathProperty, value); } } public static readonly BindableProperty AspectProperty = BindableProperty.Create((CustomImage o) => o.Aspect, default(Aspect), propertyChanged: (bindable, oldvalue, newValue) => { var eh = ((CustomImage)bindable).CustomPropertyChanged; if (eh != null) { eh(bindable, AspectProperty.PropertyName); } }); public Aspect Aspect { get { return (Aspect)GetValue(AspectProperty); } set { SetValue(AspectProperty, value); } }
Have a look at the delegate function passed in as the last parameter for each Create
function. This will be called every time the property changes; the bindable
object that comes from the first parameter of this delegate function is the object itself. We retrieve the CustomPropertyChangedEventHandler
and fire a new event to signal that a property on this object has changed.
Let's add the following to the CustomImage
class:
public event EventHandler<string> CustomPropertyChanged; protected override void OnPropertyChanged (string propertyName) { base.OnPropertyChanged (propertyName); if (propertyName == CustomImage.TintColorStringProperty.PropertyName || propertyName == CustomImage.TintOnProperty.PropertyName || propertyName == CustomImage.AspectProperty.PropertyName) { if (CustomPropertyChanged != null) { this.CustomPropertyChanged (this, propertyName); } } } }
That's all for the CustomImage
class; let's move on to the next custom control.
18.119.106.135