所以我有一个用户控件:
<StackPanel Orientation="Vertical"
Margin="10">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Stretch"
Margin="10">
<TextBlock Text="{x:Bind FileName, Mode=OneTime}"
HorizontalAlignment="Left"/>
<TextBlock Text="{x:Bind DownloadSpeed, Mode=OneWay}"
HorizontalAlignment="Right"/>
</StackPanel>
<ProgressBar Name="PbDownload"
HorizontalAlignment="Stretch" />
<TextBlock Text="{x:Bind DownloadCompletePercent, Mode=OneWay}"/>
</StackPanel>
用户控制代码:
public sealed partial class UCDownloadCard : UserControl
{
public UCDownloadCard()
{
this.InitializeComponent();
}
public string FileName { get; set; }
public string DownloadSpeed { get; set; }
public string DownloadCompletePercent { get; set; }
}
我要做的是使用此用户控件显示文件下载状态。每当启动新的下载时,我都希望以编程方式添加新的用户控件,然后在下载时更新其中的值。
目前我正在做这样的事情:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
public CancellationTokenSource CancellationTokenSource { get; set; }
public List<DownloadOperation> ActiveDownloads { get; set; } = new List<DownloadOperation>();
public List<UCDownloadCard> AddedCards { get; set; } = new List<UCDownloadCard>();
private async Task HandleDownloadAsync(DownloadOperation downloadOperation, CancellationToken cancellationToken = new CancellationToken())
{
ActiveDownloads.Add(downloadOperation);
...
...
try
{
AddDownloadProgressCard();
await downloadOperation.StartAsync().AsTask(CancellationTokenSource.Token, progressCallback);
}
finally
{
...
...
}
}
private void AddDownloadProgressCard()
{
var card = new UCDownloadCard
{
Name = $"Card{AddedCards.Count}",
FileName = "Filename.pdf",
DownloadCompletePercent = "0% completed",
DownloadSpeed = "0 KB/s"
};
AddedCards.Add(card);
OutputArea.Children.Add(card);
}
private void DownloadProgressChanged(DownloadOperation downloadOperation)
{
var downloadPercent = 100 * ((double)downloadOperation.Progress.BytesReceived / (double)downloadOperation.Progress.TotalBytesToReceive);
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
{
AddedCards[0].DownloadCompletePercent = downloadPercent.ToString();
Debug.WriteLine($"Updating Progress: {downloadPercent}%");
});
}
}
我可以将UserControl添加到OutputArea
,但其中的值不会更新。但我确信AddedCards[0].DownloadCompletePercent = downloadPercent.ToString();
正在执行多次,因为它下面的Debug.WritLine
实际上是打印到输出窗口。
如何更新UserControl中的值?
答案 0 :(得分:1)
首先,您应该使用x:Bind Mode=TwoWay
更改 UserControl 。有关详细信息,请参阅{x:Bind} markup extension。
然后,您应该实现INotifyPropertyChanged接口并实现PropertyChanged事件。您可以参考PropertyChanged事件的代码。
这是一个简单的示例,您可以参考。
UserControl.xaml,
<StackPanel Orientation="Vertical"
Margin="10">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Stretch"
Margin="10">
<TextBlock Text="{x:Bind DownloadCompletePercent, Mode=TwoWay}"/>
</StackPanel>
UserControl.xaml.cs,
public sealed partial class UCDownloadCard : UserControl, INotifyPropertyChanged
{
public UCDownloadCard()
{
this.InitializeComponent();
}
private string downloadCompletePercent;
public string DownloadCompletePercent
{
get
{
return downloadCompletePercent;
}
set
{
downloadCompletePercent = value;
RaisePropertyChanged("DownloadCompletePercent");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
然后,您可以添加此UserControl并更新其downloadCompletePercent
,
在MainPage.xaml.cs中,
private void DownloadProgress(DownloadOperation obj)
{
BackgroundDownloadProgress currentProgress = obj.Progress;
double percent;
if (currentProgress.TotalBytesToReceive > 0)
{
percent = currentProgress.BytesReceived * 100 / currentProgress.TotalBytesToReceive;
Debug.WriteLine(percent);
uCDownloadCard.DownloadCompletePercent = percent.ToString();
}
}
UCDownloadCard uCDownloadCard;
private void Button_Click_2(object sender, RoutedEventArgs e)
{
uCDownloadCard = new UCDownloadCard();
MainPagePanel.Children.Add(uCDownloadCard);
}