【问题标题】:Column in UWP DataTemplate not stretchingUWP DataTemplate 中的列未拉伸
【发布时间】:2016-08-06 17:01:07
【问题描述】:

我正在编写一个 UWP 应用程序来跟踪观看/购买/流式传输的电视节目等 试图让 DataTempate 中的网格列拉伸它们的宽度,这绝对是疯狂的,因为 XAML 中似乎存在一个忽略 * 宽度定义的错误。我需要 ListView 中的第一列(显示标题)来占用剩余空间(因此列定义 =“*”),虽然它会在 HeaderTemplate 中这样做,但它绝对拒绝在 DataTemplate 中这样做,所以整个网格最终会变得很不稳定并且不对齐,因为标题列仅使用每行所需的空间。

我的 XAML 如下 - 在 ItemTemplate DataTemplate 模板中,我绑定到一个名为 TVShow 的对象的实例,该对象位于我的主视图模型的可观察集合中。 (我没有在此处包含 ViewModel 或 TVShow 类定义,因为我知道这纯粹是 XAML 问题)。

到目前为止唯一有效的是在我的 TVShow 类中有一个额外的属性来存储列的正确宽度(通过从网格大小中减去其他三列的宽度(在后面的视图代码中获取)但是这会导致整个列表在最初显示后重新格式化,看起来很难看,更不用说糟糕的编程了。

所以我正在寻找如何解决这个问题的想法 - 我可以在主视图模型中移动属性以获得正确的列宽,但是如果我绑定到“TVShow”,我该如何绑定到模板中的那个?还是我必须从 DataTemplate 中取出内容并放入 UserControl?我已经浪费了很多时间在一些非常简单的事情上——这个错误似乎自 WPF 以来就一直存在,所以为什么 MS 从来没有修复过这个问题——非常令人沮丧。

<HubSection Name="hsShows" Width="{Binding HubSectionWidth}" MinWidth="430" MaxWidth="640" 
            VerticalAlignment="Top" HorizontalAlignment="Stretch" Background="{StaticResource Dark}" >

    <HubSection.Header>
        <TextBlock Text="Shows" TextLineBounds="TrimToBaseline" OpticalMarginAlignment="TrimSideBearings" 
                                   FontSize="24" Foreground="{StaticResource Light}"/>
    </HubSection.Header>

    <DataTemplate x:DataType="local:MainPage">

        <ListView Name="lvwShows" 
                                  Width="{Binding HubSectionGridWidth}"
                                  Grid.Row="0" 
                                  Foreground="{StaticResource Light}"
                                  Background="{StaticResource Dark}"
                                  Margin="-14,20,0,0" 
                                  Loaded="lvwShows_Loaded"
                                  ItemsSource="{Binding AllShows}"                             
                                  HorizontalAlignment="Stretch"
                                  HorizontalContentAlignment="Stretch" 
                                  IsSwipeEnabled="True"
                                  IsItemClickEnabled="True"
                                  SelectedItem="{Binding SelectedTVShow, Mode=TwoWay}"                                
                                  SelectionMode="Single"                              
                                  ScrollViewer.VerticalScrollMode="Enabled"
                                  ScrollViewer.VerticalScrollBarVisibility="Auto">

            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalAlignment" Value="Stretch" />
                </Style>
            </ListView.ItemContainerStyle>

            <ListView.HeaderTemplate>
                <DataTemplate>
                    <Grid Width="{Binding HubSectionGridWidth}" Height="Auto" Background="DarkGreen" Margin="15,5,5,5" HorizontalAlignment="Stretch">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="80"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="80"/>
                        </Grid.ColumnDefinitions>

                        <TextBlock Grid.Column="0" Text="Title" FontSize="16"  FontWeight="Bold" Foreground="{StaticResource Bright}" 
                                                   VerticalAlignment="Bottom" HorizontalAlignment="Left" 
                                                   Tag="TITLE,ASC" Tapped="ShowsGridHeading_Tapped"/>

                        <TextBlock Grid.Column="1"  Text="Seasons" FontSize="16"  FontWeight="Bold" Foreground="{StaticResource Bright}" 
                                                   VerticalAlignment="Bottom" HorizontalAlignment="Center" 
                                                   Tag="SEASONS,ASC" Tapped="ShowsGridHeading_Tapped"/>

                        <TextBlock Grid.Column="2" Text="Last Watched" FontSize="16"  FontWeight="Bold" Foreground="{StaticResource Bright}" 
                                                   VerticalAlignment="Bottom" HorizontalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" 
                                                   Tag="WATCHED,ASC" Tapped="ShowsGridHeading_Tapped"/>

                        <TextBlock Grid.Column="3" Text="Last Episode" FontSize="16"  FontWeight="Bold" Foreground="{StaticResource Bright}" 
                                                   VerticalAlignment="Bottom" HorizontalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" 
                                                   Tag="EPISODE,ASC" Tapped="ShowsGridHeading_Tapped"/>
                    </Grid>
                </DataTemplate>
            </ListView.HeaderTemplate>

            <ListView.ItemTemplate>
                <DataTemplate x:DataType="model:TVShow">
                    <Grid Height="Auto"  MinWidth="410" MaxWidth="640"  Background="Blue" HorizontalAlignment="Stretch" RightTapped="ShowsList_RightTapped">

                        <FlyoutBase.AttachedFlyout>
                            <MenuFlyout Placement="Bottom">
                                <MenuFlyoutItem x:Name="UpdateButton" Text="Update from TVMaze" Click="FlyoutUpdateButton_Click"/>
                                <MenuFlyoutItem x:Name="RefreshButton" Text="Refresh" Click="FlyoutRefreshButton_Click"/>
                                <MenuFlyoutItem x:Name="DeleteButton" Text="Delete Show" Click="FlyoutDeleteButton_Click"/>
                            </MenuFlyout>
                        </FlyoutBase.AttachedFlyout>

                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="80"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="80"/>
                        </Grid.ColumnDefinitions>

                        <TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Bind Title}"  Foreground="{StaticResource Light}"
                                                   VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="Wrap" />

                        <TextBlock Grid.Row="0" Grid.Column="1" Text="{x:Bind Seasons}"  Foreground="{StaticResource Light}"
                                                   VerticalAlignment="Center" HorizontalAlignment="Center"/>

                        <TextBlock Grid.Row="0" Grid.Column="2"   Foreground="{StaticResource Light}"
                                                   Text="{x:Bind LastWatchedDate, Mode=OneWay, Converter={StaticResource DateTimeFormatConverter}, ConverterParameter='{}{0:dd/MM/yyy HH\\\\:mm}'}"                            
                                                   VerticalAlignment="Center" HorizontalAlignment="Center"/>

                        <TextBlock Grid.Row="0" Grid.Column="3" Text="{Binding LastWatchedEpisodeRef}"  Foreground="{StaticResource Light}"
                                                   VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </DataTemplate>
</HubSection>

【问题讨论】:

    标签: c# xaml mvvm win-universal-app datatemplate


    【解决方案1】:

    如果你在视图模型中有正确的宽度,你可以像这样绑定它

    Width={Binding ElementName = ListViewname,Path=DataContext.width}
    

    【讨论】:

    • 感谢您 - 尝试过这种方式,但语法不正确,因此无法正常工作。我最终做了我在回答中所做的事情,但我对此表示赞同,因为它仍然非常有用。
    【解决方案2】:

    这个问题是由ListViewItem的默认模板引起的,要使Grid在项目内部伸展,你可以打开文档大纲标签=>找到你的ListView控件并右键单击它,然后选择Edit Additional Templates =>选择Edit Generated Item Container (ItemContainerStyle),最后Edit a Copy .

    然后你会在你的页面资源中找到这个模板,请修改代码:

    <Setter Property="HorizontalContentAlignment" Value="Left" />
    

    收件人:

    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    

    那么你的问题就可以解决了。

    我看到你有不止一个ListView,如果你想让这个样式定位到这个页面中的所有ListView,你可以删除这个模板的x:Key属性并用StaticResource删除ItemContainerStyle由upper动作生成。

    别灰心,我想你以前开发过WPF,学习UWP很容易。编辑模板或控件的样式可以解决很多布局问题,这里有一些default templates and styles of different controls,下次遇到此类问题时可以看看。

    如果您对如何开发 UWP 应用有疑问,可以参考Develop UWP apps,如果您对 API 有问题,可以参考Reference for Universal Windows apps

    如果您需要帮助或建议,可以在这里提问,这里的人很乐意提供帮助。

    【讨论】:

    • 感谢 Grace - 这是我所做的,但并不像进入 Blend 那样复杂(您需要获得火箭科学学位才能使用),请参阅我所做的回答。
    【解决方案3】:

    好的,所以我最终将这个 XAML 添加到了我的 ListViews 中(虽然我知道我可以按照 Grace 的建议做,但我发现 Blend 使用起来很糟糕)——Horizo​​ntalContentAlignment 确实起到了作用!

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalAlignment" Value="Stretch" />
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        </Style>
    </ListView.ItemContainerStyle>
    

    【讨论】:

    • 是的,我建议修改的值是这个HorizontalContentAligment属性。
    猜你喜欢
    • 2017-02-26
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 2016-05-27
    • 2016-10-27
    • 2017-04-11
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多