bugfix> c# > 投稿

だから私はユーザーコントロールを持っています:

<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の値を更新するにはどうすればよいですか?

回答 1 件
  • まず、あなたが変更する必要がありますUserControl x:Bind Mode=TwoWay で 詳細については、{x:Bind}マークアップ拡張機能を参照してください。

    次に、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);
    }
    
    

あなたの答え