代码之家  ›  专栏  ›  技术社区  ›  t. YILMAZ

当我从tcp客户机接收数据时,我无法从viewmodels的xaml页面进行更改

  •  0
  • t. YILMAZ  · 技术社区  · 6 年前

    我在研究Xamarin.forms和wpf。我被困在这里:

    我的应用程序中有TCP服务器,当我的TCP服务器从客户端接收数据时,我的事件(位于ViewModelBase中)将触发,然后它必须在当前的XAML页上显示数据,但它不显示。任何人都知道我应该如何将此事件绑定到当前的xaml页面。

    我想要的是,当TCP客户机向我发送数据(它只是字符串)时,我想用displayAlert在屏幕上显示这些数据。

    如果我用按钮,它会起作用,但不是我想要的。

    ViewModelBase类

    public class ViewModelBase : BindableBase, INavigationAware, IDestructible
    {
        protected INavigationService NavigationService { get; private set; }
        protected IPageDialogService DialogService { get; private set; }
    
        public static ProxyServer Client { get; set; }
        public ObservableCollection<Item> ListItems { get; set; }
    
        private DelegateCommand _eventCommand;
        public DelegateCommand EventCommand
        {
            get { return _eventCommand; }
            set { SetProperty(ref _eventCommand, value); }
        }
        public DelegateCommand DisconnectCommand { get; set; }
    
        private object _lockObj = new object();
    
        public ViewModelBase(INavigationService navigationService,IPageDialogService dialogService)
        {
            Client = ProxyServer.GetInstance();
    
            EventCommand = new DelegateCommand(Client_ListenServer, () => { return true; });
            DisconnectCommand = new DelegateCommand(Disconnect, () => { return true; });
    
            NavigationService = navigationService;
            DialogService = dialogService;
            ListItems = new ObservableCollection<Item>()
            {
                new Item()
                {
                    Id = "0",
                    Name = "Android",
                    Description = "Android Mobil"
                },
                new Item()
                {
                    Id = "1",
                    Name = "IOS",
                    Description = "IOS Mobil"
                },
                  new Item()
                {
                    Id = "2",
                    Name = "UWP",
                    Description = "UWP Mobil + From"
                }
            }; // sample
        }
    
        private void Client_ListenServer()
        {
            Debug.WriteLine("I'm triggered");
            DialogService.DisplayAlertAsync("test title", "message", "OK !", "cancel");
        }
    
        private void Disconnect()
        {
            Client.Disconnect();
            RemoveEventHandler();
            DialogService.DisplayAlertAsync("Status", "Disconnected..", "OK");
        }
    
        #region NavigationMethods
        public virtual void OnNavigatedFrom(NavigationParameters parameters)
        {
            RemoveEventHandler();
        }
        public virtual void OnNavigatedTo(NavigationParameters parameters)
        {
            if (Client.ConnectedStatus())
                AddEventHandler();
        }
        public virtual void OnNavigatingTo(NavigationParameters parameters) 
        {
            RemoveEventHandler();
        }
    
        public virtual void Destroy()
        {
    
        }
        #endregion
    
        private void Client_ListenServer(object sender, EventArgs e)
        {
            Client_ListenServer(); // this method must show dialogAlert on current page
        }
    
        public void RemoveEventHandler()
        {
            Client.ListenServer -= Client_ListenServer;
        }
        public void AddEventHandler()
        {
            Client.ListenServer += Client_ListenServer;
        }
    }
    

    客户端侦听器方法触发器,但显示警报不起作用。

    当前的xaml页。

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
                 prism:ViewModelLocator.AutowireViewModel="True"
                 x:Class="DataViewer.Views.Login"
                 Title="{Binding Title}">
        <ContentPage.Content>
            <StackLayout VerticalOptions="CenterAndExpand" Spacing="20" Padding="20"> 
                <Entry  Text="{Binding Username}" Placeholder="Username"/>
                <Entry Text="{Binding Password}" Placeholder="Password" IsPassword="true"/>
                <Button Text="Login" VerticalOptions="CenterAndExpand" Command="{Binding AuthorizeCommand}"/>
    
            </StackLayout>
        </ContentPage.Content>
        <ContentPage.ToolbarItems>
            <ToolbarItem Name="MenuItem1" Order="Secondary" Text="Connect" Command="{Binding ConnectCommand}"/>
            <ToolbarItem Name="MenuItem2" Order="Secondary" Text="Disconnect" Command="{Binding DisconnectCommand}" />
            <ToolbarItem Name="MenuItem2" Order="Secondary" Text="Get Data" Command="{Binding EventCommand}" />
        </ContentPage.ToolbarItems>
    </ContentPage>
    

    我的app.cs

    public partial class App : PrismApplication
        {
            public App() : this(null) { }
    
            public App(IPlatformInitializer initializer) : base(initializer) { }
    
            protected override async void OnInitialized()
            {
                InitializeComponent();
                await NavigationService.NavigateAsync("NavigationPage/ConnectionPage");
            }
    
            protected override void RegisterTypes(IContainerRegistry containerRegistry)
            {
                containerRegistry.RegisterForNavigation<NavigationPage>();
                containerRegistry.RegisterForNavigation<Login, LoginViewModel>();
                containerRegistry.RegisterForNavigation<Views.ListView, ListViewModel>();
                containerRegistry.RegisterForNavigation<Item, ItemViewModel>();
                containerRegistry.RegisterForNavigation<ConnectionPage>();
            }
        }
    

    Android主活动类

      [Activity(Label = "DataViewer", Icon = "@mipmap/ic_launcher", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
        public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
        {
            protected override void OnCreate(Bundle bundle)
            {
                TabLayoutResource = Resource.Layout.Tabbar;
                ToolbarResource = Resource.Layout.Toolbar;
    
                base.OnCreate(bundle);
                UserDialogs.Init(this);
                global::Xamarin.Forms.Forms.Init(this, bundle);
                LoadApplication(new App(new AndroidInitializer()));
            }
    
        }
    
        public class AndroidInitializer : IPlatformInitializer
        {
            public void RegisterTypes(IContainerRegistry container)
            {
                // Register any platform specific implementations
            }
        }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Jason    6 年前

    你需要使用

    Device.BeginInvokeOnMainThread( () => {
      // whatever UI operation you need goes here
    });
    

    从后台线程强制在主(ui)线程上执行ui代码