Привязка данных UWP: изменение свойства в обработчике событий не обновляет интерфейс - PullRequest
0 голосов
/ 18 апреля 2019

Я пытаюсь связать данные (режим OneWay), полученные через Bluetooth LE, с TextBlock, но не могу заставить его работать.

У меня есть одна главная страница, которая содержит другую дополнительную страницу.Эта вторичная страница имеет 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 #, для вторичной страницы, регистрируетсяобработчик, который получает уведомления от устройства Bluetooth и сохраняет их в свойстве 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 изменены,пользовательский интерфейс не обновляется.У кого-нибудь есть идеи почему?Я уже потратил много часов, пытаясь решить эту проблему.

Но когда SData обновляется обработчиком события PointerPressed, запускается элементом прямоугольника, все работает нормально.

 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;
            });

Есть идеи, почему обновление одним хадлером работает, а другим - нет?Может ли это быть вызвано определением Accel_x на другой странице, чем цель?

1 Ответ

0 голосов
/ 18 апреля 2019

Итак, наконец, я понял это.После добавления 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();
                });
            };
...