I'm currently working on different exercises in order to understand bindings for UserControls.
I have following UserControl:
<UserControl x:Class="Overvaagning.View.AccGyrValues"
xmlns:vm="clr-namespace:Overvaagning.Model"
mc:Ignorable="d" Width="404.478" Height="467.164">
<UserControl.DataContext>
<vm:Accelerometer/>
</UserControl.DataContext>
<Grid Margin="10,0,0,0">
<Label x:Name="labelValX" Content="{Binding Path=xValue}" HorizontalAlignment="Left" Margin="282,51,0,0" VerticalAlignment="Top" FontSize="30" RenderTransformOrigin="0.519,0.24" Width="88" Height="44"/>
</Grid>
And a ViewModel:
public class Accelerometer : Values, INotifyPropertyChanged, Overvaagning.Model.Values.ISensorOperations
{
public SensorAccelerometer BTAccSensor { get; internal set; }
// Property changed event handleren initialiseres
public event PropertyChangedEventHandler PropertyChanged;
// Her initiliserer jeg Universalt Entydigt Identification (UUID) for at få adgang til Accelerometer tjenesten i kittet
static Guid SensorDeviceUuid = Guid.Parse("F000AA10-0451-4000-B000-000000000000");
public Accelerometer()
{
// Definer sensoren til en accelerometer sensor.
BTAccSensor = new SensorAccelerometer();
// Sensoren service UUID defineres til Accelerometer UUID.
BTAccSensor.SensorDeviceUuid = SensorDeviceUuid;
// Denne UUID er en karakteristisk UUID i accelerometer tjenesten der har opgaven til at aktivere accelerometeret
BTAccSensor.DataUuid = Guid.Parse("F000AA11-0451-4000-B000-000000000000");
// Denne UUID bruges til at konfigurere acceleromteret
BTAccSensor.ConfigurationUuid = Guid.Parse("F000AA12-0451-4000-B000-000000000000");
// Denne UUID bruges til at modificere acceleromter følsomheden, alt afhængig af, hvor mange notifikationer
// accelerometer skal sende pr. sekund
BTAccSensor.SpeedUuid = Guid.Parse("F000AA13-0451-4000-B000-000000000000");
// PropertyChanged defineres til den metode der skal kaldes, så snart der modtages data fra accelerometet
BTAccSensor.PropertyChanged += sensor_PropertyChanged;
}
public sbyte XRaw { get; internal set; }
public sbyte YRaw { get; internal set; }
public sbyte ZRaw { get; internal set; }
public byte ValueToSend;
public double X { get; internal set; }
public double Y { get; internal set; }
public double Z { get; internal set; }
public double G { get; internal set; }
public static Task<IList<Values.SensorInitData>> CreateAllAsync(Readings readings, FrameworkElement el)
{
return SensorCreateAll<Accelerometer>.CreateAllAsync(SensorDeviceUuid, readings, el);
}
public Task<int> InitializeAsync(GattDeviceService device, Readings readings, FrameworkElement el, byte ValueToSend)
{
return BTAccSensor.InitializeAsync(device, readings, el, ValueToSend);
}
private string _xval;
public string xValue
{
get { return _xval; }
set
{
if (value != _xval)
{
_xval = value;
OnPropertyChanged("xValue");
}
}
}
public void sensor_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
sbyte value;
switch (e.PropertyName)
{
case "B0Raw":
value = (sbyte)BTAccSensor.B0Raw;
if (value != XRaw)
{
XRaw = value;
X = value / 16.0;
X = Math.Round(X, 2);
xValue = X.ToString();
}
break;
case "B1Raw":
value = (sbyte)BTAccSensor.B1Raw;
if (value != YRaw)
{
YRaw = value;
Y = ((double)(sbyte)value) / 16.0;
Y = Math.Round(Y, 2);
G = Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
G = Math.Round(G, 2);
}
break;
case "B2Raw":
value = (sbyte)BTAccSensor.B2Raw;
if (value != ZRaw)
{
ZRaw = value;
Z = ((double)(sbyte)value) / 16.0;
Z = Math.Round(Z, 2);
}
break;
}
}
// Metoden for propertychanged eventhandler
protected virtual void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
I'm actually binding the label content to string xValue. Everytime I receive a data from an external sensor, the sensor_PropertyChanged()
method is triggered, and I actually want to define the xValue as the double X
I'm receiving from the sensor. The problem is that the propertyChangedEventHandler
becomes always equals to null
. Why does this problem occur ?, since I'm sure of the binding between the View and VievModel actually works.