【问题标题】:Event inside a custom renderer not firing自定义渲染器中的事件未触发
【发布时间】:2018-07-28 20:48:38
【问题描述】:

我正在制作一个 xamarin.form 应用程序, 我有一个自定义渲染,用于在视图中流式传输相机,我已经按照这里的教程进行操作:

camera stream tutorial

我已经成功地在视图中正确显示了相机流,现在我正在尝试创建一个切换闪光灯的按钮:

这是我的自定义渲染器:

using System;
using System.Diagnostics;
using Hangover.Camera.Factory;
using Hangover.GUIPersonalizzata;
using Xamarin.Forms;

//Questa classe permette di visualizzare lo stream della fotocamera
namespace Hangover.Camera.Views
{
    public class CameraStream:View
    {
        public static readonly BindableProperty CameraProperty = BindableProperty.Create(
        propertyName: "Camera",
        returnType: typeof(CameraOptions),
        declaringType: typeof(CameraStream),
        defaultValue: CameraOptions.Rear);

        //Funzioni Fotocamera
        private Fotocamera _fotocamera;
        public event EventHandler flash_event;

        //costruttore di convenienza
        public CameraStream()
        {
        }

        public CameraStream(Fotocamera fotocamera){
            _fotocamera = fotocamera;
        }

        public CameraOptions Camera
        {
            get { return (CameraOptions)GetValue(CameraProperty); }
            set { SetValue(CameraProperty, value); }

        }

        public void gestisciFlash(BottoneSwitch btn){
            if (flash_event != null)
                flash_event.Invoke(btn, null);
        }

    }
}

这里是 iOS 实现:

using System;
using System.Diagnostics;
using Hangover.Camera.Factory;
using Hangover.Camera.Views;
using Hangover.GUIPersonalizzata;
using Hangover.iOS.CustomRenderer;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(CameraStream), typeof(CameraStreamRenderer))]
namespace Hangover.iOS.CustomRenderer
{
    public class CameraStreamRenderer : ViewRenderer<CameraStream, UICameraPreview>,ICameraFunctions 
    {
        UICameraPreview uiCameraPreview; // fotocamera nativa

        protected override void OnElementChanged(ElementChangedEventArgs<CameraStream> elem)
        {
            base.OnElementChanged(elem);

            if (Control == null)
            {
                uiCameraPreview = new UICameraPreview(elem.NewElement.Camera);
                SetNativeControl(uiCameraPreview);

                var camera_stream = (CameraStream)elem.NewElement;
                camera_stream.flash_event += (object sender, EventArgs e) => {
                    Debug.Write("teeeest");
                };

            }
        }

        //Invocato quando la view viene chiusa
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                Control.CaptureSession.Dispose();
                Control.Dispose();
            }

            base.Dispose(disposing);
        }


        public void attivaFlash()
        {
            Debug.Write("flash");
            Debug.Write("flash");
            Debug.Write("flash");
        }

        public void distattivaFlash()
        {
            throw new NotImplementedException();
        }

        public void scattaFoto()
        {
            throw new NotImplementedException();
        }

        public void ruotaFotocamera(BottoneSwitch btn)
        {
            if (!btn.isON){// mostro la post
                Debug.Write("mostra fotocamera post");
            }else{//mostra ant
                Debug.Write("mostra fotocamera ant");
            }
        }
    }
}

所以使用这个事件:

public void gestisciFlash(BottoneSwitch btn){
            if (flash_event != null)
                flash_event.Invoke(btn, null);
        }

我应该可以打印“teeest”,但 flash_event 总是为空,我不知道该怎么做。

我已经尝试过firing custom render event 此处提供的解决方案,但没有成功。

有什么建议吗?

编辑

protected override void OnElementChanged(ElementChangedEventArgs<CameraStream> e)
        {

            if(e.OldElement != null){

            }

            if(e.NewElement != null){

                if (Control == null)
                {
                    uiCameraPreview = new UICameraPreview(new Camera.CameraOptions());
                    SetNativeControl(uiCameraPreview);
                }

                var camera_stream = (CameraStream)e.NewElement;
                camera_stream.flash_event += (object sender, EventArgs ea) => {
                    attivaFlash();
                };
            }

            base.OnElementChanged(e);
        }

按照@Benl 的建议重构了代码仍然无法正常工作,这个:

 public void gestisciFlash(BottoneSwitch btn){
                if (flash_event != null)
                    flash_event.Invoke(btn, null);
            }

仍然为空。

【问题讨论】:

    标签: android ios forms xamarin cross-platform


    【解决方案1】:

    编辑:

    假设:连接了一些生成闪光灯/手电筒事件的相机设备。

    CameraStreamRenderer.cs:

    OnElementChanged(ElementChangedEventArgs<CameraStream> e)
    {
        base.OnElementChanged(e);
    
        if (Control == null)
        {
            // Instantiate the native control and assign it to the Control property with
            // the SetNativeControl method
            uiCameraPreview = new UICameraPreview(e.NewElement.Camera);
            SetNativeControl(uiCameraPreview);
        }
    
        if (e.OldElement != null)
        {
            // Unsubscribe from event handlers and cleanup any resources
            uiCameraPreview.Flash -= OnFlash;
        }
        if (e.NewElement != null)
        {
            // Configure the control and subscribe to event handlers
            uiCameraPreview.Flash += OnFlash;
        }
    }
    
    void OnFlash(object sender, EventArgs e)
    {
        Debug.WriteLine("Flash");
    }
    

    但是,flash 事件必须在某处生成,原始问题中未显示。

    假设flash 事件可能在Observer 中的UICameraPreview 中生成,假定密钥为"torchActive"。

    UICameraPreview.cs:

    public event EventHandler<EventArgs> Flash;
    
    protected virtual void OnFlash()
    {
        Flash?.Invoke(this, new EventArgs());
    }
    
    void Initialize()
    {
        ...
        AVCaptureDevice device = ...
        ...
        if (device == null)
        {
            return;
        }
    
        device.AddObserver(
                key: "torchActive", 
                options: NSKeyValueObservingOptions.New, 
                observer: (c) => 
                    { 
                        OnFlash(); 
                    });
    

    device.RemoveObserver 上面没有显示。

    【讨论】:

    • 感谢您的输入,但该事件仍为空。也许我做错了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2021-03-25
    相关资源
    最近更新 更多