在 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
}
}
这个问题与编程有关,但如果需要更改,也与我的架构有关。
基本上,我将 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
}
}