c# - UWP 数据绑定:事件处理程序中的属性更改不会更新 UI
问题描述
我正在尝试使用 TextBlock 绑定通过蓝牙 LE 接收的数据(单向模式),但我无法使其工作。
我有一个包含另一个辅助页面的主页。此辅助页面将 TextBlock 用作 Grid 列内的目标:
<Grid x:Name="DataPanel"
RelativePanel.Below="ControlPanel"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="ax_down0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Transparent" Grid.Column="0" />
<StackPanel Orientation="Vertical" Margin="10" Grid.Column="0" HorizontalAlignment="Center"
DataContext="">
<TextBlock Text="Accelerometr X" TextAlignment="Center" FontWeight="Bold"/>
<TextBlock Name="ADataX" Text="{x:Bind Path=SData.Acceleration_x, Mode=OneWay}" TextAlignment="Center"/>
</StackPanel>
<Rectangle x:Name="ax_up0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Transparent" Grid.Column="0"/>
.
.
.
</Grid>
用作源的类如下所示:
public class SensorData : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private UInt16 acceleration_x;
public UInt16 Acceleration_x
{
get
{
return acceleration_x;
}
set
{
acceleration_x = value;
OnPropertyChanged("Acceleration_x");
}
}
.
.
.
public SensorData()
{
Acceleration_x = 0;
Acceleration_y = 0;
Acceleration_z = 0;
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// Raise the PropertyChanged event, passing the name of the property whose value has changed.
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
接下来,在 C# 文件中,对于辅助页面,注册了从蓝牙设备接收通知并将其存储到 SData 属性中的处理程序(属性 Accel_x 具有 GattCharacteristic 类型并在 MainPage 中定义,其实例可通过 rootPage 变量访问)
public sealed partial class Page2 : Page
{
private MainPage rootPage;
public SensorData SData { get; set; }
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
rootPage.Accel_x.ValueChanged += delegate (GattCharacteristic sender, GattValueChangedEventArgs args)
{
var reader = DataReader.FromBuffer(args.CharacteristicValue);
SData.Acceleration_x = reader.ReadByte();
};
}
即使 SData 中的数据发生更改,UI 也不会更新。有谁知道为什么?我已经花了很多时间试图解决它。
但是,当 PointerPressed 事件处理程序更新 SData 时,由矩形元素触发它可以正常工作。
ax_up0.PointerPressed += new PointerEventHandler(delegate (object sender, PointerRoutedEventArgs e)
{
e.Handled = true;
ax_down0.Fill = new SolidColorBrush(Windows.UI.Colors.DimGray);
UInt16 i = SData.Acceleration_x;
i++;
SData.Acceleration_x = i;
});
知道为什么一个 hadler 有效而另一个不更新吗?这可能是由于在不同页面中定义 Accel_x 而不是目标引起的吗?
解决方案
所以,最后我想通了。将 Dispatcher 添加到 ValueChanged 处理程序后,它开始工作:
rootPage.Accel_x.ValueChanged += async delegate (GattCharacteristic sender, GattValueChangedEventArgs args)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
var reader = DataReader.FromBuffer(args.CharacteristicValue);
SData.Acceleration_x = reader.ReadByte();
});
};
推荐阅读
- java - 包含为两个相同的对象返回 false
- jquery - 在 React 中动态构建渲染函数
- ios - 滚动时 didDeselectItemAt 崩溃
- javascript - 如何获取动态创建的下拉列表的值?
- gnuplot - 如何使用 Gnuplot 在一个图中绘制代表数据集中多个子集行的多个图表?
- python - Pandas 将使用逗号而不是小数点分隔符的数字从对象转换为数字
- r - 如何在 R 中使用配对列按列排列数据框?
- html - 更改显示给用户的结果中的字体
- ios - XCODE:iPhone 12 的尺寸将如何影响约束和情节提要?
- mysql - 计算来自同一列mysql的时间戳之间的时间差(以分钟为单位)