我是MAUI的新手,我对tcp侦听器有问题。侦听器工作正常,但在(CollectionView(处的UI中没有可视化信号。UI中的(CollectionView(保持冻结。当CollectionView上的用户clicl显示缓冲信号并再次停止以对所选行进行下一次更改时。我尝试异步任务和线程,但没有成功。我哪里错了?请帮忙!
C#代码
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Xml;
using Microsoft.Maui.Controls;
using Npgsql;
namespace Black_Program;
public partial class SignalsPage : ContentPage
{
public static bool searchRedy = true;
public static int daysNotPayedAlarm = 60;
System.Threading.Thread ReadTerminalSignals;
public SignalsPage()
{
InitializeComponent();
Task.Run(async () => await ReadFromIp());
}
async Task ReadFromIp()
{
var terminalSignalsList = new List<string>();
int terminalSignalsCount = 0;
TcpClient tcpclnt = new TcpClient();
try
{
while (true)
{
try
{
tcpclnt.Connect(MainPage.sqlServerIP, MainPage.sqlServerTerminalPort);
}
catch (Exception)
{
}
while (tcpclnt.Connected)
{
Thread.Sleep(10);
string messege = string.Empty;
Stream stream = tcpclnt.GetStream();
byte[] bytes = new byte[1024];
int length = stream.Read(bytes, 0, 1024);
/* Convert from ascii to stream */
for (int i = 0; i < length; i++)
messege += (Convert.ToChar(bytes[i]));
//byte[] utfBytes = Encoding.Default.GetBytes(messege);
messege = Encoding.UTF8.GetString(bytes);
try
{
////Update new signal if object selected
string[] newMessages = messege
.Split(new char[] { '-' }
, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
if (signals_number_search.Text == newMessages[0].TrimEnd())
{
string numberData = signals_number_search.Text.Replace(" ", string.Empty); ;// Read the input from the user.
DateTime time = DateTime.Now;
string dateToday = time.AddDays(1).ToString("yyyy'-'MM'-'dd"); // 2 days log
string dateBefore = time.AddDays(-5).ToString("yyyy'-'MM'-'dd");
ShowSignalsFromLogDB(numberData, dateToday, dateBefore);
}
}
catch (Exception)
{
}
//Application.Current.MainPage.Dispatcher.Dispatch(() => terminalSignalsList.Add(messege));
terminalSignalsList.Add(messege);
signals_terminal.ItemsSource = terminalSignalsList;
terminalSignalsCount++;
Application.Current.MainPage.Dispatcher.Dispatch(() => signals_terminal.ScrollTo(terminalSignalsCount));
}
}
}
catch (Exception)
{
}
}
UI代码
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Black_Program.SignalsPage"
Title="Сигнали">
<ScrollView
BackgroundColor="Black">
<!-- Navigation Menu-->
<!-- Test design -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="AUTO"/><!--0-->
<RowDefinition Height="AUTO"/><!--1-->
<RowDefinition Height="AUTO"/><!--2-->
<RowDefinition Height="AUTO"/><!--3-->
<RowDefinition Height="AUTO"/><!--4-->
<RowDefinition Height="AUTO"/><!--5-->
<RowDefinition Height="AUTO"/><!--6-->
<RowDefinition Height="AUTO"/><!--7-->
</Grid.RowDefinitions>
<!-- Cool Adres and Users -->
<HorizontalStackLayout
HeightRequest="{OnPlatform Default='40',iOS='40',Android='35'}"
Margin="{OnPlatform Default='5,0,10,0',iOS='5,0,5,0',Android='5,0,5,0'}"
Grid.Row="1"
HorizontalOptions="CenterAndExpand">
<ScrollView>
<CollectionView
MaximumHeightRequest="300"
x:Name="signals_terminal"
SelectionMode="Single">
<CollectionView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Няма данни</x:String>
</x:Array>
</CollectionView.ItemsSource>
</CollectionView>
</ScrollView>
</Frame>
</Grid>
</ScrollView>
</ContentPage>
- 将更改移动到terminalSignalsList,并在调度内部设置ItemsSource。原因:任何影响UI的东西,在MainThread(Dispatcher线程(上运行都是最安全的
- 最终项目的索引比计数少1。(你的计数太高了。(
- REMOVE
<ScrollView>
-CollectionView自己滚动。(嵌套滚动可能会造成干扰。( - 不需要Dispatcher.Dispatch和MainThread.Invoke…两者都可以。结果:
Application.Current.MainPage.Dispatcher.Dispatch(() =>
{
terminalSignalsList.Add(messege);
signals_terminal.ItemsSource = terminalSignalsList;
signals_terminal.ScrollTo(terminalSignalsList.Count - 1));
}