WPF - UI 未更新,但 debug.writeline 正确更新

问题描述 投票:0回答:1

早上好,我一直在尝试为我的应用程序创建一个更新程序,并且几乎得到了最终结果,但是我似乎无法让 UI 报告进度,我已经设置了 Onpropertychanged 事件和下载的异步任务,但不会反映在 ui 中

我有下载代码,

private async Task DownloadUpdateAsync(string url, string destinationPath)
{
using (var client = new HttpClient())
{
    var response = await client.GetAsync(url, 
    HttpCompletionOption.ResponseHeadersRead);
    response.EnsureSuccessStatusCode();

    var totalBytes = response.Content.Headers.ContentLength ?? 0;
    var readBytes = 0L;
    var buffer = new byte[8192];
    using (var stream = await response.Content.ReadAsStreamAsync())
    using (var fileStream = new FileStream(destinationPath, FileMode.Create, 
    FileAccess.Write, FileShare.None))
    {
        await Task.Run(async () =>
        {
            while (true)
            {
                var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
                if (bytesRead == 0)
                {
                    await Task.Yield();
                    break;
                }

                await fileStream.WriteAsync(buffer, 0, bytesRead);
                readBytes += bytesRead;

                Application.Current.Dispatcher.Invoke(() => {
                    DownloadProgress = (int)((readBytes / (float)totalBytes) * 100);
                    Process = DownloadProgress.ToString(); // Convert to string
                    OnPropertyChanged(nameof(DownloadProgress));
                    OnPropertyChanged(nameof(Process)); // Notify property change for Process
                    Debug.WriteLine(Process); // Print the Process value
                });
            }
        });
    }
}

}

我一直在尝试让进度条工作,但是注意到 debug.writeline 工作了,所以排除了它是 int 转换,我对文本框做了同样的事情,但仍然没有更新

Int 设置

        public int DownloadProgress
    {
        get => downloadProgress;
        set
        {
            if (downloadProgress != value)
            {
                downloadProgress = value;
                OnPropertyChanged(nameof(DownloadProgress));
            }
        }
    }

已在 onpropertyChanged 事件上设置断点行,它确实收到了更新的值,但未在 UI 中反映这一点

XAML

<Window.DataContext>
    <viewmodel:UpdateViewModel/>
</Window.DataContext>


<Window.Resources>
    <Style x:Key="CustomProgressBar" TargetType="ProgressBar">
        <Setter Property="Foreground" Value="#DCA3FF"/>
        <Setter Property="Background" Value="#7C8093"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Height" Value="20"/>
    </Style>
</Window.Resources>



<Grid>
    <Border Background="#7C8093" CornerRadius="5">
        <StackPanel>
            <TextBlock Foreground="White" Text="An update is available."/>
            <TextBlock Foreground="White" Text="Change Log: update test"/>
            <Button  Content="Update Now" Command="{Binding UpdateCommand}" />
            <ProgressBar Height="20" Value="{Binding DownloadProgress, Mode=OneWay}" />
            <TextBlock Width="700" Text="{Binding Process, UpdateSourceTrigger=PropertyChanged}"/>
            <Button Content="Test Progress" Command="{Binding TestProgressCommand}" />
            

        </StackPanel>
    </Border>
    
    

</Grid>

我很确定我有这个,我已经搜索过,甚至在写在这里之前使用过chatgpt,但仍然有问题,反映了下载的进度

输出窗口,证明调试已获得更新并显示下载过程

我已尽力提供有关该问题的尽可能多的信息。

c# wpf data-binding progress-bar
1个回答
0
投票

当前使用

ProgressBar
的一个问题是,您分配的值不超过 100,但没有设置栏上的
Maximum
属性(默认为
1
)。对于任何 1 或以上的值,这将导致进度条显示为 100%,从而呈现未更新的外观。

只需尝试这个:

 <ProgressBar Maximum="100" 
              Height="20" 
              Value="{Binding DownloadProgress, Mode=OneWay}" />
        

此外(尽管不太可能是问题的原因),对您问题的评论是正确的;你不需要在这里使用

Task.Run
,如果你不使用
Task.Run
,你也不需要使用
Dispatcher.Invoke
。而且你不需要
Task.Yield
;当“bytesRead”为
break
时,只是
0

© www.soinside.com 2019 - 2024. All rights reserved.