Events 我试图更新Xamarin.Forms中的一个标签,结果它破坏了整个应用程序
我的应用程序主页上有一个标签,应该每隔十五秒更新一次,但是它只更新一次,之后,很多事情都停止了。例如,如果我尝试在标签更新后打开一个新页面,页面标题将与“后退”按钮绘制在同一位置(这两个按钮都是由Xamarin在工具栏中生成的),并且页面内容根本不会加载。此外,我在页面上有一个ListView,如果我尝试选择一个项目(应该打开一个新页面),它只在第一次工作,之后ListView消失,但显示在所选项目后面的橙色框保持不变 标签目前的工作原理是,我在App类中有一个计时器,它从我加载到App的OnStart()函数(该部分工作正常)的列表中选择一段随机文本,然后触发一个应该更新标签的事件Events 我试图更新Xamarin.Forms中的一个标签,结果它破坏了整个应用程序,events,xamarin.forms,label,Events,Xamarin.forms,Label,我的应用程序主页上有一个标签,应该每隔十五秒更新一次,但是它只更新一次,之后,很多事情都停止了。例如,如果我尝试在标签更新后打开一个新页面,页面标题将与“后退”按钮绘制在同一位置(这两个按钮都是由Xamarin在工具栏中生成的),并且页面内容根本不会加载。此外,我在页面上有一个ListView,如果我尝试选择一个项目(应该打开一个新页面),它只在第一次工作,之后ListView消失,但显示在所选项目后面的橙色框保持不变 标签目前的工作原理是,我在App类中有一个计时器,它从我加载到App的OnS
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Timers;
using System.Reflection;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Partylist.Views;
using Partylist.Models;
namespace Partylist
{
public partial class App : Application, INotifyPropertyChanged
{
// Variable to store the currently selected event.
public static Event selectedEvent;
// Variable to store the currently selected list.
public static PartylistList selectedList;
// Struct to store information about tips.
public struct Tip
{
// A short version of the tip for the banner at the bottom of the screen.
public string Summary { get; set; }
// The full tip, which you can read by clicking the "More" button in the banner.
public string Full { get; set; }
}
// Array of tips.
public List<Tip> tips = new List<Tip>();
// Current tip.
public Tip CurrentTip { get; set; }
// Timer that gets the tip to update.
public Timer tipTimer = new Timer(15000);
// Random number generator for choosing the tip.
public Random rand = new Random();
// Event that tells the tip banners on the pages to update.
public static event EventHandler TipUpdate;
// Constructor.
public App()
{
// Do whatever initialization stuff this does.
InitializeComponent();
// Subscribes the timer's event handling function to its event.
tipTimer.Elapsed += OnTimerElapsed;
// Open the first page: the list of events.
MainPage = new NavigationPage(new EventsPage()) {
BarTextColor = Color.FromHex("FF4081")
};
}
// Loads tips data.
private void LoadTips()
{
// Variable for the assembly.
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(App)).Assembly;
// Variable for the stream I use to read the text file.
Stream tipsStream = assembly.GetManifestResourceStream("Partylist.Resources.tips.txt");
// And a variable for the StreamReader.
StreamReader tipsReader = new StreamReader(tipsStream);
// Read the whole file into the list of tips.
while (!tipsReader.EndOfStream)
{
// Read a line into a "sumamry" variable.
string sum = tipsReader.ReadLine();
// Read another line into a "full" variable.
string full = tipsReader.ReadLine();
// Add an item to the list of tips that uses "summary" as the summary
// and "full" as the full tip.
tips.Add(new Tip()
{
Summary = sum,
Full = full
});
}
// Random index of the chosen tip.
int index = rand.Next(tips.Count);
// Set the current tip as the tip at that index.
CurrentTip = tips.ElementAt(index);
// Start timer (if it needs it).
tipTimer.Start();
}
// Event handling function for when the timer goes off.
private void OnTimerElapsed(object source, ElapsedEventArgs e)
{
// Random index of the chosen tip.
int index = rand.Next(tips.Count);
// Set the current tip as the tip at that index.
CurrentTip = tips.ElementAt(index);
// Fire the event to update the pages' tip banners.
TipUpdate?.Invoke(this, e);
}
// Standard lifecycle events.
protected override void OnStart()
{
// Call a function that loads the tips.
LoadTips();
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.IO;
使用System.Linq;
使用系统计时器;
运用系统反思;
使用Xamarin.Forms;
使用Xamarin.Forms.Xaml;
使用Partylist.Views;
使用Partylist.Models;
名称空间Partylist
{
公共部分类应用程序:应用程序,INotifyPropertyChanged
{
//变量来存储当前选定的事件。
公共静态事件选择事件;
//变量来存储当前选定的列表。
公共静态PartyList selectedList;
//结构来存储有关提示的信息。
公共结构提示
{
//屏幕底部横幅提示的简短版本。
公共字符串摘要{get;set;}
//完整提示,您可以通过单击横幅中的“更多”按钮来阅读。
公共字符串已满{get;set;}
}
//一系列提示。
公共列表提示=新列表();
//当前提示。
公共提示CurrentTip{get;set;}
//获取要更新的提示的计时器。
公共定时器tipTimer=新定时器(15000);
//用于选择尖端的随机数生成器。
公共随机兰德=新随机();
//事件,通知页面上的提示横幅进行更新。
公共静态事件EventHandler TipUpdate;
//构造器。
公共应用程序()
{
//做任何初始化的事情。
初始化组件();
//将计时器的事件处理函数订阅到其事件。
tipTimer.Appeased+=OnTimeRecursed;
//打开第一页:事件列表。
MainPage=新导航页面(新事件页面()){
BarTextColor=Color.FromHex(“FF4081”)
};
}
//加载提示数据。
私有void加载提示()
{
//程序集的变量。
var assembly=IntrospectionExtensions.GetTypeInfo(typeof(App)).assembly;
//用于读取文本文件的流的变量。
Stream tipsStream=assembly.GetManifestResourceStream(“Partylist.Resources.tips.txt”);
//和StreamReader的一个变量。
StreamReader tipsReader=新StreamReader(tipsStream);
//将整个文件读入提示列表。
而(!tipsReader.EndOfStream)
{
//将一行读入“sumamry”变量。
string sum=tipsReader.ReadLine();
//将另一行读入“full”变量。
string full=tipsReader.ReadLine();
//向使用“摘要”作为摘要的提示列表中添加一项
//“完整”作为完整提示。
添加(新提示()
{
汇总=总和,
满的
});
}
//所选尖端的随机索引。
int index=rand.Next(tips.Count);
//将当前提示设置为该索引处的提示。
CurrentTip=tips.ElementAt(索引);
//启动计时器(如果需要)。
tipTimer.Start();
}
//计时器关闭时的事件处理功能。
私有void onTimeRecursed(对象源,ElapsedEventArgs e)
{
//所选尖端的随机索引。
int index=rand.Next(tips.Count);
//将当前提示设置为该索引处的提示。
CurrentTip=tips.ElementAt(索引);
//触发事件以更新页面的提示横幅。
TipUpdate?调用(此,e);
}
//标准生命周期事件。
受保护的覆盖void OnStart()
{
//调用加载提示的函数。
加载提示();
}
受保护的覆盖void OnSleep()
{
}
受保护的覆盖void OnResume()
{
}
}
}
在页面的OnAppearing()方法中,我将标签的文本设置为当前提示(此时为null),并订阅函数,将其更新为计时器触发的事件
using Partylist.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Partylist.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EventsPage : ContentPage
{
// Text of the tip banner.
public string BannerText { get; set; }
// List of events, used to populate
// the page's ListView (see the XAML).
public ObservableCollection<Event> EventList { get; set; }
// Constructor.
public EventsPage()
{
// Does all the stuff to make the page
// exist that doesn't involve anything
// specific to this particular page in
// this particular app.
InitializeComponent();
// Set the label's BindingContext to the
// App class so it can update its text.
tipLabel.BindingContext = (App)App.Current;
}
// Runs when the page appears.
protected override void OnAppearing()
{
// Call the regular OnAppearing method.
base.OnAppearing();
// Set the BindingContext of the page to itself.
BindingContext = this;
// Update the ListView.
UpdateListView();
// Set the banner's text to the current tip's sumamry.
tipLabel.Text = ((App)App.Current).CurrentTip.Summary;
OnPropertyChanged("CurrentTip");
// Subscribe the OnTipUpdate function to the tipUpdate event in the app
// class.
App.TipUpdate += OnTipUpdate;
}
// Function to update the ListView whent he page loads or when something changes.
private void UpdateListView()
{
// Set the EventList to a new ObservableCollection
// which will be populated.
EventList = new ObservableCollection<Event>();
// Loop to populate the ObservableCollection.
for (int i = 0; i < Directory.GetDirectories(
Environment.GetFolderPath(
Environment.SpecialFolder
.LocalApplicationData))
.Length; i++)
{
// Add a new event.
EventList.Add(new Event()
{
// Set the folder name to the name of the folder
// that the even corresponds to.
FolderName = new DirectoryInfo(Directory.GetDirectories(
Environment.GetFolderPath(
Environment.SpecialFolder
.LocalApplicationData))[i]).Name,
// Sets the date/time created to the folder's
// creation date.
DateCreated = Directory
.GetCreationTime(Directory.GetDirectories(
Environment.GetFolderPath(
Environment.SpecialFolder
.LocalApplicationData))[i]),
// Sets the date/time last edited to the
// folder's write date.
DateEdited = Directory
.GetLastWriteTime(Directory.GetDirectories(
Environment.GetFolderPath(
Environment.SpecialFolder
.LocalApplicationData))[i])
});
// Set the ItemsSource of the ListView in the
// XAML to the ObservableCollection.
EventsListView.ItemsSource = EventList;
// Calls OnPropertyChanged() which makes the ListView update.
OnPropertyChanged("EventList");
}
}
// Function to go to the "New Event" page.
async void OnNewEventClicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new NewEventPage());
}
// Function for when a ListView item is selected.
async void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
App.selectedEvent = (Event)e.SelectedItem;
await Navigation.PushAsync(new ListsPage());
}
// Function to delete an event if the "Delete" context action is selected.
async void OnDelete(object sender, EventArgs e)
{
// Represents the thing to be deleted.
var del = (MenuItem)sender;
// Displays a confirmnation popup and stores the user's answer in a variable.
var answer = await DisplayAlert("Delete this event?",
"Are you sure you want to delete the event: \"" +
((Event)del.CommandParameter).FolderName + "\"?", "Delete", "Cancel");
// If the user accepted, delete the event with the MenuItem that ran this function.
if (answer)
{
Directory.Delete(Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData),
((Event)del.CommandParameter).FolderName), true);
// Set the ItemsSource to null and back to make the ListView update.
EventsListView.ItemsSource = null;
UpdateListView();
}
}
// Function for when the current tip updates.
public void OnTipUpdate(object sender, EventArgs e)
{
// Make the label's text update.
tipLabel.Text = ((App)App.Current).CurrentTip.Summary;
OnPropertyChanged("CurrentTip");
}
}
}
使用Partylist.Models;
使用制度;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.IO;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用Xamarin.Forms;
使用Xamarin.Forms.Xaml;
名称空间Partylist.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
公共部分类事件页面:ContentPage
{
//提示横幅的文本。
公共字符串BannerText{get;set;}
//事件列表,用于填充
//页面的列表视图(参见XAML)。
公共ObservableCollection事件列表{get;set;}
//构造器。
公共活动
{
//做所有的事情,使网页
//不存在的存在
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Partylist.Views.EventsPage"
Title="Events"
BackgroundColor="White">
<ContentPage.ToolbarItems>
<ToolbarItem IconImageSource="settings_gear.png"
Priority="0"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<!--Main layout of the page-->
<StackLayout>
<!--ListView of the events-->
<ListView x:Name="EventsListView"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!--These contewxt actions are buttons that appear
when you long press the item (Android) or swipe
left (iOS).-->
<ViewCell.ContextActions>
<MenuItem Clicked="OnDelete"
CommandParameter="{Binding .}"
Text="Delete"
IsDestructive="true"/>
</ViewCell.ContextActions>
<!--This is the content that actually appears-->
<StackLayout Padding="20,5">
<Label Text="{Binding FolderName}"
TextColor="#FF7700"
FontSize="Large"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--"New Event" button-->
<Button Text="+ Add New Event"
TextColor="#ff418b"
FontSize="Large"
BackgroundColor="#00ffffff"
Clicked="OnNewEventClicked"/>
<!--The banner at the bottom of the screen that gives tips-->
<Frame BorderColor="#ff418b"
Padding="0">
<FlexLayout Direction="Row"
AlignItems="Stretch"
JustifyContent="SpaceBetween">
<!--The "Tip" icon-->
<Image Source="tip_icon.png"
Margin="10"
FlexLayout.Basis="50"/>
<!--The short version of the tip-->
<Label x:Name="tipLabel"
VerticalTextAlignment="Center"
TextColor="#bb0099"
FontSize="Medium"
FontAttributes="Bold"
FlexLayout.Basis="250"/>
<!--The button that opens up a screen
with tyhe rest of the tip-->
<Button Text="More"
TextColor="White"
FontAttributes="Bold"
FontSize="Medium"
BackgroundColor="#ff418b"
FlexLayout.Basis="100"/>
</FlexLayout>
</Frame>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Device.BeginInvokeOnMainThread (() => {
label.Text = "Async operation completed";
});