问题描述
在 WinUI3 中,我想在加载资源期间向 Window 用户提供更新。每次加载资源时,我都想设置 TextBlock 的文本。我尝试过直接设置文本,执行两种方式的数据绑定和使用 INotifyPropertyChanged。但是对于我的生活,我不能做更新 UI 这么简单的事情。是的,我在网上到处搜索,但没有任何效果。
请为我提供一个简单的 c# 和 xaml 示例,该示例在我加载资源时实时更新文本块。谢谢。
这是我尝试过的。
XAML:
<StackPanel x:Name="LoadingStackPanel" >
<ProgressRing x:Name="LoadingProgressRing" IsActive="True" IsHitTestVisible="True" />
<TextBlock x:Name="ProgresstextBlock" Text="{x:Bind Path=GetData,Mode=TwoWay}" />
</StackPanel>
方法一:
public event PropertyChangedEventHandler PropertyChanged;
private string _data = "Loading...";
private void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(prop));
}
}
public string GetData
{
get { return _data; }
set
{
_data = value;
OnPropertyChanged("GetData");
}
}
然后设置 GetData
属性。
方法二:
ProgresstextBlock.Text = "Loading resource ...";
方法三:
dispatcherQueue.TryEnqueue(() => {
ProgresstextBlock.Text = "Loading resource ...";
});
方法四:
dispatcherQueue.TryEnqueue(() => {
GetData = "Loading resource ...";
});
解决方法
我设法完成了我需要做的事情,因此我将我的答案发布给可能对解决方案感兴趣的任何其他人。
以下代码将显示 ProgressRing 和 TextBlock。 TextBlock 的文本将使用正在加载的网站的名称进行更新。加载完所有网站后,隐藏进度指示面板,显示主页面板。
XAML:
<Window
x:Class="CH11_ResponsiveWinUI3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:DefaultBindMode="TwoWay"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Visible">
<StackPanel x:Name="ProgressPanel">
<ProgressRing IsActive="True" />
<TextBlock x:Name="ProgressUpdater" Text="Loading..." TextAlignment="Left" TextWrapping="WrapWholeWords" TextTrimming="CharacterEllipsis" />
</StackPanel>
<StackPanel x:Name="HomePanel" Visibility="Collapsed">
<TextBlock Text="Home Window" />
</StackPanel>
</StackPanel>
</Window>
背后的代码:
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace CH11_ResponsiveWinUI3
{
public sealed partial class MainWindow : Window
{
private DispatcherTimer _timer;
public MainWindow()
{
InitializeComponent();
_timer = new();
_timer.Interval = TimeSpan.FromSeconds(3);
_timer.Tick += Timer_Tick;
_timer.Start();
}
private async void Timer_Tick(object sender,object e)
{
_timer.Stop();
_timer.Tick -= Timer_Tick;
await GetWebsitesAsync();
}
private List<string> WebsiteLinks()
{
List<string> websiteLinks = new();
ProgressUpdater.Text = "Loading...";
websiteLinks.Add("https://docs.microsoft.com");
websiteLinks.Add("https://www.youtube.com");
websiteLinks.Add("https://www.abovetopsecret.com/index.php");
websiteLinks.Add("https://dotnet.microsoft.com/apps/aspnet");
websiteLinks.Add("https://www.packtpub.com/free-learning");
websiteLinks.Add("https://smile.amazon.com/");
return websiteLinks;
}
private async Task GetWebsitesAsync()
{
Dictionary<string,string> websites = new();
foreach(string website in WebsiteLinks())
{
string contents = await Task.Run(() => new WebClient().DownloadString(website));
websites.Add(website,contents);
ProgressUpdater.Text = $"\nURL: {website},downloaded...";
}
ProgressUpdater.Text = "\nLoading completed.";
Thread.Sleep(1000);
ProgressPanel.Visibility = Visibility.Collapsed;
HomePanel.Visibility = Visibility.Visible;
}
}
}
我希望你觉得这很有用。