在 class 之外传递和事件处理程序

Passing and event handler outside class

这个问题与编程有关,但如果需要更改,也与我的架构有关。

基本上,我将 Microsoft Band 功能封装在 class 中,我在 class 中有一个方法订阅加速度计的变化如下:

_bandClient.SensorManager.Accelerometer.ReadingChanged += Accelerometer_ReadingChanged;

我希望能够从 class 外部调用一个方法(事件处理程序),所以我这样做了:

public async Task ToggleAccelerometer(EventHandler<BandSensorReadingEventArgs<IBandAccelerometerReading>> del)
        {
            if (!_sensorState[Sensor.Accelerometer])
            {
                _sensorState[Sensor.Accelerometer] = true;
                _bandClient.SensorManager.Accelerometer.ReadingChanged += del;
                await _bandClient.SensorManager.Accelerometer.StartReadingsAsync();
            }
            else
            {
                _sensorState[Sensor.Accelerometer] = false;
                await _bandClient.SensorManager.Accelerometer.StopReadingsAsync();
            }
        }

并且参数del实现如下:

private void Accelerometer_ValuesChanged(object sender, BandSensorReadingEventArgs<IBandAccelerometerReading> e)
        {
            IBandAccelerometerReading accelerometer = e.SensorReading;
            Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            IBandAccelerometerReading accelerometer = e.SensorReading;
            AccelXBlock.Text = accelerometer.AccelerationX.ToString();
            AccelYBlock.Text = accelerometer.AccelerationY.ToString();
            AccelZBlock.Text = accelerometer.AccelerationZ.ToString();
        }).AsTask();
        }

这是按预期工作的,我的问题是:

我应该改变我的程序吗 设计(我想做的是不好的做法吗?),如果是这样,那么更好的方法是什么?

理想情况下,您应该在包装器中进行事件冒泡 class。您可以看到它如何使用 event 实现 Publisher/Subscriber 模式。见下文:

// Wrapper
public class BandManager
{
    // Callers will subscribe to this event
    public event EventHandler<BandSensorReadingEventArgs<IBandAccelerometerReading>> ReadingChanged;

    public async Task ToggleAccelerometer()
    {
        if (!_sensorState[Sensor.Accelerometer])
        {
            _sensorState[Sensor.Accelerometer] = true;
            _bandClient.SensorManager.Accelerometer.ReadingChanged += OnReadingChanged;
            await _bandClient.SensorManager.Accelerometer.StartReadingsAsync();
        }
        else
        {
            _sensorState[Sensor.Accelerometer] = false;
            await _bandClient.SensorManager.Accelerometer.StopReadingsAsync();
        }
    }

    private void OnReadingChanged(object sender, BandSensorReadingEventArgs<IBandAccelerometerReading> e)
    {
        var readingChangedHandler = ReadingChanged;

        if(readingChangedHandler != null)
        {
            ReadingChanged(this, e);
        }
    }
}

// Client
public class MainClass
{
    public async void Test()
    {
        var bandManager = new BandManager();
        bandManager.ReadingChanged += BandManager_ReadingChanged;
        var whatever = await bandManager.ToggleAccelerometer();
    }

    // This is event handler for your wrapper class
    private void BandManager_ReadingChanged(object sender, BandSensorReadingEventArgs<IBandAccelerometerReading> e)
    {
        // use 'e' as you need
    }
}