UWP - 以编程方式显示ItemTemplate中的进度条

时间:2017-07-12 06:24:19

标签: c# xaml gridview uwp uwp-xaml

我正在为Windows Mobile构建一个UWP应用程序,但我对进度条有点麻烦。我在应用程序启动的第一页上有一个工作,这很好,但现在我正在尝试在GridView中显示一个。我一次会在屏幕上有N个GridView控件,并希望在每个控件中显示一个ProgressBar。

这适用于数据绑定和数据将显示,但当我尝试在TextBlock之前添加不确定的ProgressBar时,它似乎没有显示。我只能假设我要么把它放在错误的地方,要么我做错了因为我的GridView正在使用GridView.ItemTemplate

以下是一些截图:

Without data in the collection

With data in the collection

使用答案更新

在Justin XL的帮助下,我成功地解决了问题。我绑定到普通的clr属性而不是DependencyProperty。我更改了代码以使用MVVM并设置IsLoaded属性来处理通知UI。这是我更新和工作的代码:

ViewModel.cs

public class ViewModel
{
    public string Name { get; set; }
}

MainPageViewModel.cs

public class MainPageViewModel : INotifyPropertyChanged
{
    public ObservableCollection<ViewModel> MyData { get; set; } = new ObservableCollection<ViewModel>();

    private bool _isLoaded;

    public bool IsLoaded
    {
        get { return _isLoaded; }
        set
        {
            _isLoaded = value;
            OnPropertyChanged();
        }
    }

    public async Task GetDataAsync()
    {
        // Add items to MyData
        IsLoaded = true;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

MainPage.xaml.cs中

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        InitializeComponent();
        DataContext = new MainPageViewModel();
    }

    public MainPageViewModel Vm => DataContext as MainPageViewModel;

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        await Vm.GetDataAsync();
    }
}

MainPage.xaml中

<Page
    x:Class="MultiGridProgressBars.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MultiGridProgressBars"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:models="using:MultiGridProgressBars.Models"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <GridView IsHitTestVisible="{x:Bind Vm.IsLoaded, Mode=OneWay}"
            Header="A Grid View"
            HorizontalAlignment="Left"
            x:Name="MyDataListView1"
            ItemsSource="{x:Bind Vm.MyData}"
            Width="164" 
            Margin="10,53,0,53">
            <GridView.ItemTemplate>
                <DataTemplate x:DataType="models:ViewModel">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" HorizontalAlignment="Stretch" TextWrapping="WrapWholeWords">
                            <Run Text="{ x:Bind Name }"></Run>
                        </TextBlock>
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>
            <GridView.ItemContainerStyle>
                <Style TargetType="GridViewItem">
                    <Setter Property="Margin" Value="0 0 0 10"></Setter>
                    <Setter Property="BorderThickness" Value="1"></Setter>
                    <Setter Property="BorderBrush" Value="Blue"></Setter>
                    <Setter Property="Padding" Value="5"></Setter>
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                    <Setter Property="HorizontalAlignment" Value="Stretch"/>
                    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                    <Setter Property="VerticalAlignment" Value="Stretch"/>
                    <Setter Property="Width" Value="150"></Setter>
                    <Setter Property="Height" Value="80"></Setter>
                </Style>
            </GridView.ItemContainerStyle>
        </GridView>
    </Grid>
</Page>

的App.xaml

<Application
        x:Class="MultiGridProgressBars.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:MultiGridProgressBars"
        xmlns:converters="using:MultiGridProgressBars.Converters"
        RequestedTheme="Light">

    <Application.Resources>
        <converters:InvertIsCheckedVisiblityConverter x:Key="InvertIsCheckedVisiblityConverter" />
        <Style TargetType="GridView">
            <Setter Property="Padding" Value="0,0,0,10" />
            <Setter Property="IsTabStop" Value="False" />
            <Setter Property="TabNavigation" Value="Once" />
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
            <Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="False" />
            <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled" />
            <Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True" />
            <Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
            <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
            <Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True" />
            <Setter Property="IsSwipeEnabled" Value="True" />
            <Setter Property="ItemContainerTransitions">
                <Setter.Value>
                    <TransitionCollection>
                        <AddDeleteThemeTransition />
                        <ContentThemeTransition />
                        <ReorderThemeTransition />
                        <EntranceThemeTransition IsStaggeringEnabled="False" />
                    </TransitionCollection>
                </Setter.Value>
            </Setter>
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <ItemsWrapGrid Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="GridView">
                        <Grid BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}">
                            <ScrollViewer x:Name="ScrollViewer"
                                            AutomationProperties.AccessibilityView="Raw"
                                            BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
                                            HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                            HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                            IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                            IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}"
                                            IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}"
                                            IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                            IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                            TabNavigation="{TemplateBinding TabNavigation}"
                                            VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                            VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                            ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
                                <ItemsPresenter FooterTransitions="{TemplateBinding FooterTransitions}"
                                                FooterTemplate="{TemplateBinding FooterTemplate}"
                                                Footer="{TemplateBinding Footer}"
                                                HeaderTemplate="{TemplateBinding HeaderTemplate}"
                                                Header="{TemplateBinding Header}"
                                                HeaderTransitions="{TemplateBinding HeaderTransitions}"
                                                Padding="{TemplateBinding Padding}" />
                            </ScrollViewer>

                            <ProgressBar x:Name="StatusBar"
                                             Visibility="{Binding IsHitTestVisible, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InvertIsCheckedVisiblityConverter}}"
                                             IsIndeterminate="True" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

InvertIsCheckedVisiblityConverter.cs

public class InvertIsCheckedVisiblityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        bool isChecked = (bool) value;
        return isChecked ? Visibility.Collapsed : Visibility.Visible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return null;
    }
}

1 个答案:

答案 0 :(得分:3)

如果您想要位于ProgressBar中心的GridView,则需要将GridView包裹在Grid内并放置ProgressBarGridView之上。像这样的东西 -

<Grid>
    <GridView />

    <ProgressBar x:Name="StatusBar"
                 IsIndeterminate="True"></ProgressBar>
</Grid>

当然,您只想在加载数据时显示它正在进行中,因此您需要一个实现IsLoading的{​​{1}}之类的属性,然后将INotifyPropertyChanged绑定到它。

IsIndeterminate

更新

为了简化,您还可以将IsIndeterminate="{Binding IsLoading}" 包裹在ProgressBar样式中。首先,根据默认样式生成新样式,然后转到GridView并将根面板从ControlTemplate更改为Border,然后只需放置Grid就像这样 -

ProgressBar

您还需要 bool 属性来控制<ControlTemplate TargetType="GridView"> <Grid BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <ScrollViewer x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"> <ItemsPresenter FooterTransitions="{TemplateBinding FooterTransitions}" FooterTemplate="{TemplateBinding FooterTemplate}" Footer="{TemplateBinding Footer}" HeaderTemplate="{TemplateBinding HeaderTemplate}" Header="{TemplateBinding Header}" HeaderTransitions="{TemplateBinding HeaderTransitions}" Padding="{TemplateBinding Padding}" /> </ScrollViewer> <ProgressBar x:Name="StatusBar" IsIndeterminate="{Binding IsHitTestVisible, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InvertBoolConverter}}" /> </Grid> </ControlTemplate> 的加载。在这里,我们可以使用现有属性ProgressBar。请注意,您还需要使用转换器反转该值。

最后,您可以直接操作加载视觉效果 -

IsHitTestVisible