【问题标题】:WPF ViewBox inside of a StackPanelStackPanel 内的 WPF ViewBox
【发布时间】:2018-03-17 12:48:51
【问题描述】:

我正在尝试显示类似于记分板的东西,团队名称在正方形的前 25% 中,分数占较低的 75%(适当的字体比例)。我还希望这些控件随着窗口大小的调整而增长/缩小。

为此,我创建了一个网格并将其分成*3* 行。我已将一个 TextBlock 添加到顶行,另一个 TextBlock 跨越底部 4 行。然后我将每个 TextBox 包装在 ViewBox 中

这会导致应用程序进入“中断模式”。

这说明了问题:

<Window x:Class="WpfRandoms.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfRandoms"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="3*"/>
        </Grid.RowDefinitions>

        <ListView ItemsSource="{Binding Teams}" HorizontalAlignment="Center" Grid.Row="0" BorderBrush="{x:Null}" Background="{x:Null}">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}">
                    <Setter Property="Background" Value="Transparent" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListViewItem}">
                                <ContentPresenter />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Border Margin="10" Padding="10" CornerRadius="5" Width="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*" />
                                <RowDefinition Height="3*" />
                            </Grid.RowDefinitions>
                            <Viewbox Grid.Row="0">
                                <TextBlock Text="{Binding Name}" TextAlignment="Center" />
                            </Viewbox>
                            <Viewbox Grid.Row="1">
                                <TextBlock Text="{Binding Score}" FontSize="40" TextAlignment="Center" />
                            </Viewbox>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>

使用代码隐藏:

using System.Collections.Generic;
using System.Windows;

namespace WpfRandoms
{
    public partial class MainWindow : Window
    {
        public class Team
        {
            public string Name { get; set; }
            public int Score { get; set; }
        }

        public IList<Team> Teams { get; private set; }

        public MainWindow()
        {
            InitializeComponent();

            Teams = new List<Team>();
            Teams.Add(new Team() { Name = "Team A", Score = 78 });
            Teams.Add(new Team() { Name = "Team B", Score = 1 });
            Teams.Add(new Team() { Name = "Team C", Score = 101 });

            DataContext = this;
        }
    }
}

这似乎是由用作 ListView 的 ItemsPanelTemplate 的 StackPanel 引起的(没有此 StackPanel 一切正常,但布局不理想)。但是,我不知道另一种使 ListView 水平的方法,所以我被 StackPanel 困住了。

在对 ViewBox 的工作原理以及 StackPanels 的行为方式进行了一些试验和阅读之后,我找到了一些解决方案(可能不是最好的解决方案)。
我将我的 ListView 包装在一个 Border 中,然后将 ListView 的 DataTemplate 中的 Border 高度绑定到 Border 外部的高度。
因此有一个小的限制 - 主要是顶部/底部边距导致 ListView 的元素被修剪。为了避免这种修剪,我在 DataTemplate 中的边框中添加了填充,然后在其中添加了一个较小的边框,其中包含背景等。
我还必须隐藏 ListView 的垂直滚动条。
这是我所拥有的:

<Window x:Class="WpfRandoms.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="3*"/>
        </Grid.RowDefinitions>

        <Border x:Name="MyBorder" Margin="10" Grid.Row="0">
            <ListView ItemsSource="{Binding Teams}" HorizontalAlignment="Center" VerticalAlignment="Stretch" BorderBrush="{x:Null}" Background="{x:Null}" ScrollViewer.VerticalScrollBarVisibility="Hidden">
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
                <ListView.ItemContainerStyle>
                    <Style TargetType="{x:Type ListViewItem}">
                        <Setter Property="Background" Value="Transparent" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListViewItem}">
                                    <ContentPresenter />
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListView.ItemContainerStyle>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Border Margin="10, 0" Padding="10" Height="{Binding ActualHeight, ElementName=MyBorder}" Width="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}">
                            <Border Background="AliceBlue" CornerRadius="5">
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="3*" />
                                    </Grid.RowDefinitions>
                                    <Viewbox Grid.Row="0">
                                        <TextBlock Text="{Binding Name}" TextAlignment="Center"/>
                                    </Viewbox>
                                    <Viewbox Grid.Row="1">
                                        <TextBlock Text="{Binding Score}" FontSize="40" TextAlignment="Center"/>
                                    </Viewbox>
                                </Grid>
                            </Border>
                        </Border>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Border>
    </Grid>
</Window>

如果有更好的解决方案,我将不胜感激:)

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    我不确定我是否完全理解您的问题。如果您希望保持名称和分数之间的比率相同,您可以使用“*”作为名称(25%)和“3*”作为分数(75%)。您还可以将每个 TextBlock 放在 Viewbox 中,而不是整个东西。为了简单起见,我用硬编码字符串替换了转换器和绑定。

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Border Margin="10" Padding="10" CornerRadius="5" Background="Coral">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="3*" />
                </Grid.RowDefinitions>
                <Viewbox Grid.Row="0">
                    <TextBlock Text="Home" TextAlignment="Center" />
                </Viewbox>
                <Viewbox Grid.Row="1" >
                    <TextBlock Grid.Row="1" Text="25" TextAlignment="Center" />
                </Viewbox>
            </Grid>
        </Border>
    </Grid>
    

    【讨论】:

    • 再次,一旦我将我的 TextBoxes 包装在 ViewBox 中(与您的代码相同),一旦显示此视图,我就会在 VisualStudio 中收到“应用程序处于中断模式”消息。
    【解决方案2】:

    我认为您在边界控件上引用的转换器可能有问题。

    我在没有绑定的情况下测试了您的 XAML,并且视图框按预期工作。

     <Border Margin="10" Padding="10" CornerRadius="5" Width="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}">
            <Viewbox>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="Team Name" TextAlignment="Center" Grid.Row="0" />
                    <TextBlock Text="100" FontSize="100" TextAlignment="Center" Grid.Row="1" Grid.RowSpan="3"/>
                </Grid>
            </Viewbox>
        </Border>
    

    希望这会有所帮助!

    【讨论】:

    • 我做了同样的事情(删除绑定),这仍然进入中断模式。如果它在 ListView.ItemTemplate.DataTemplate 中会有所不同吗? (这就是现在的位置,因为我有一个团队列表)
    • 你能发布你所有的 XAML 吗?
    猜你喜欢
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多