在网格内以编程方式创建多个进度条

时间:2011-11-23 10:12:54

标签: wpf grid progress-bar

我想通过代码(VB.Net)在网格或表格中创建多个进度条。结构布局如下:

Game 1      [ Progress Bar 1 ]
            Downloading 2MB of 4MB

Game 2      [ Progress Bar 2 ]
            Downloading 4MB of 5MB

Game 3      [ Progress Bar 3 ]
            Download completed

需要能够实时更新所选进度条的值。 我应该创建一个新类并在这个类中添加一个进度条数组吗?


编辑:

假设我合并了建议的答案,使用ItemsControl在show_progress_page(UI)中显示我的进度条组。我有另一个download_page实际上使用WebClient DownloadFileAsync来下载所有游戏。

如何在download_page中添加功能以便能够在show_progress_page中创建进度条?

我已尝试创建此类download_page但在加载UI后没有显示此新进度条

Public Class download_page 
Public CollectionDownloads As New ObservableCollection(Of [DownloadAppViewModel])()

Public Sub New()
    InitializeComponent()
    Dim individualDownload As New DownloadAppViewModel()
    individualDownload.GameName = "hello"
    individualDownload.TotalSize = 20
    individualDownload.DownloadedSize = 5
    CollectionDownloads.Add(individualDownload)
End Sub

End Class

2 个答案:

答案 0 :(得分:3)

使用MVVM pattern;)

非常容易

创建一个代表每次转移的类:

public class GameDownloadViewModel : ViewModelBase
{
    private string _gameName;
    public string GameName
    {
        get { return _gameName; }
        set
        {
            _gameName = value;
            OnPropertyChanged("GameName");
        }
    }

    public string StatusText
    {
        get
        {
            if (_downloadedSize < _totalSize)
                return string.Format("Downloading {0} MB of {1} MB", _downloadedSize, _totalSize);
            return "Download completed";
        }
    }

    private long _totalSize;
    public long TotalSize
    {
        get { return _totalSize; }
        set
        {
            _totalSize = value;
            OnPropertyChanged("TotalSize");
            OnPropertyChanged("Progress");
            OnPropertyChanged("StatusText");
        }
    }

    private long _downloadedSize;
    public long DownloadedSize
    {
        get { return _downloadedSize; }
        set
        {
            _downloadedSize = value;
            OnPropertyChanged("DownloadedSize");
            OnPropertyChanged("Progress");
            OnPropertyChanged("StatusText");
        }
    }

    public double Progress
    {
        get
        {
            if (_totalSize != 0)
                return 100.0 * _downloadedSize / _totalSize;
            return 0.0;
        }
    }
}

ItemsControl绑定到ObservableCollection<GameDownloadViewModel>,并定义用于显示每个项目的模板:

<ItemsControl ItemsSource="{Binding GameDownloads}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="200" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0"
                           Text="{Binding GameName}" >
                <ProgressBar Grid.Row="0" Grid.Column="1"
                             Minimum="0" Maximum="100" Value="{Binding Progress}" />
                <TextBlock Grid.Row="1" Grid.Column="1"
                           Text="{Binding StatusText}" >
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

当进度发生变化时,只需更新相关GameDownloadViewModel的属性,视图就会相应更新。

答案 1 :(得分:2)

不要创建一个进度条数组,创建一个可绑定的类,对需要显示的数据进行建模,然后将所述类的集合绑定到ItemsControl,该模板具有其中一个模板的形式网格行:

<ItemsControl ItemsSource="{Binding Data}"
              Grid.IsSharedSizeScope="True">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <!-- Synchronize size accross rows,
                         works in conjunction with Grid.IsSharedSizeScope. -->
                    <ColumnDefinition SharedSizeGroup="A" />
                    <ColumnDefinition SharedSizeGroup="B" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <TextBlock Text="{Binding GameName}" />
                <ProgressBar Grid.Column="1" Minimum="0" Maximum="1" Value="{Binding DownloadProgress}" />
                <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding DownloadProgressString}"/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

然后您只需更新下载对象的属性,UI就会反映更改。