У меня есть некоторый пользовательский элемент управления из github, который и каждый раз, когда что-то меняется от этого элемента управления, мне нужно отправить сообщение сокета tcp с некоторыми условиями на модель представления.У меня OnPropertyChanged в коде позади представления, которое вызывает функцию sendMessage в viewModel.
Сообщение отправляется правильно, но условия (свойства viewmodel) не берутся из фактических значений.Например: у меня есть свойство IsEnabled bool, которое имеет значение true, но считывает false в функции sendMessage при доступе через поток OnPropertyChanged.
Я могу только представить, что событие OnPropertyChanged вызывается из другого потока, который не можетдоступ к значениям основного потока, поэтому я попробовал следующее:
Device.BeginInvokeOnMainThread(() =>
MainViewModel.getInstance().Joystick.sendMsg(JoystickControl.Distance,
JoystickControl.Angle));
Это будет код для пользовательского элемента управления, который работает нормально, в xaml:
<CustomControls:JoystickControl x:Name="JoystickControl"
Grid.Row="4" BackgroundColor="#ececec"
HorizontalOptions="Center"
VerticalOptions="Center"
Margin="0,10" BindingContext="{Binding
Joystick}" PropertyChanged="JoystickControl_PropertyChanged"
IsEnabled="{Binding IsJoystickEnabled}">
</CustomControls:JoystickControl>
Это будет мой полный код:
private void JoystickControl_PropertyChanged(object sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
if (Application.Current.MainPage != null)
{
Device.BeginInvokeOnMainThread(() =>
MainViewModel.getInstance().Joystick.sendMsg(JoystickControl.Distance,
JoystickControl.Angle));
}
}
Это будет моя собственность, которую мне нужно оценить:
public bool IsTeachFlag { get; set; }
Я также пробовал с этим:
private bool isTeaching;
public bool IsTeaching
{
get { return this.isTeaching; }
set { SetValue(ref this.isTeaching, value); }
}
В приведенном выше примере вызывается метод SetValue для вызова при изменении свойства
У меня есть функция sendMessage:
public async void sendMsg(double distance, double angle)
{
Response = new Response();
if (IsTeachFlag) {
MainViewModel.getInstance().SelectedDevice.Message = "TEACHING,Distance=" + distance.ToString() + "&Angle=" + angle.ToString(); }
else { MainViewModel.getInstance().SelectedDevice.Message = "DATA,Distance=" + distance.ToString() + "&Angle=" + angle.ToString(); }
Response.Message = tcpService.sendMessage(MainViewModel.getInstance().SelectedDevice);
if (Response.Message.Contains("FormatException"))
{
Response.IsSuccess = false;
await Application.Current.MainPage.DisplayAlert(Languages.Error, Languages.FormatValidation, Languages.Accept);
return;
}
else if (Response.Message.Contains("ArgumentNullException") ||
this.Response.Message.Contains("SocketException") || this.Response.Message.Contains("Exception"))
{
Response.IsSuccess = false;
await Application.Current.MainPage.DisplayAlert(Languages.Error, this.Response.Message, Languages.Accept);
return;
}
else if (Response.Message.Contains("OK"))
{
Response.IsSuccess = true;
}
if (Response.IsSuccess)
{
}
else
{
await Application.Current.MainPage.DisplayAlert(Languages.Error, Languages.tcpMessageError, Languages.Accept);
}
}
Я также пробовал без асинхронной работы, и результаты те жеЯ никогда не получаю значение IsTeachFlag, когда оно истинно.Я пробовал и с другими свойствами.
Что мне в основном нужно, это вызвать событие при перемещении джойстика.Я пробовал GestureRecognizer (swipe) и некоторые другие вещи, и это то, что заставило его работать лучше.
Что я могу сделать, чтобы получить доступ к свойствам viewmodel, чтобы получить фактическое значение в главном потоке?