Элементы Gridview в виде квадратов в WinRT (метро)

Я боролся с этим несколько дней и не могу заставить его работать. Может быть, я не такой хороший программист XAML, как я надеялся :)

Во всяком случае, моя проблема в том, что я хочу привязать несколько элементов к GridView и заставить их отображаться в виде квадратов без установки какой-либо ширины и высоты. Причина этого в том, что я хочу, чтобы мои элементы GridView увеличивались/сокращались и расширялись до максимального размера при изменении разрешения или размера экрана.

Вот мой XAML:

<UserControl.Resources>

    <Style x:Key="MyItemContainerStyle" TargetType="ListViewItem">
        <Setter Property="FontFamily" Value="Segoe UI" />
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="VerticalContentAlignment" Value="Stretch" />
        <!--<Setter Property="Height" Value="{Binding RelativeSource={RelativeSource Self}, Path=Width}" />-->
    </Style>

    <DataTemplate x:Key="MyItemTemplate">
        <Border CornerRadius="4" 
                BorderBrush="Black"  
                BorderThickness="1"
                Background="Blue">
            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">X</TextBlock>
        </Border>
    </DataTemplate>

    <ItemsPanelTemplate x:Key="MyItemsPanelTemplate">
        <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" />
    </ItemsPanelTemplate>

</UserControl.Resources>

<Grid Background="White">
    <GridView x:Name="MyGrid"
              UseLayoutRounding="True"
              ItemTemplate="{StaticResource MyItemTemplate}"
              ItemsPanel="{StaticResource MyItemsPanelTemplate}"
              ItemContainerStyle="{StaticResource MyItemContainerStyle}"
              ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
    </GridView>
</Grid>

И это мой код:

public sealed partial class BlankPage : Page
{
    public BlankPage()
    {
        this.InitializeComponent();

        MyGrid.Items.Add(new ListViewItem { Content = 1 });
        MyGrid.Items.Add(new ListViewItem { Content = 2 });
        MyGrid.Items.Add(new ListViewItem { Content = 3 });
    }

    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.  The Parameter
    /// property is typically used to configure the page.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }
}

Однако это приводит к такому выводу (прямоугольные элементы, а не квадраты):

Вывод

Я был бы признателен, если бы кто-то, кто знает немного больше о разработке XAML и WinRT (metro), чем я, мог бы объяснить это для меня и, возможно, привести мне рабочий пример.

Спасибо!

ИЗМЕНИТЬ

Мне посоветовали обернуть мою границу в окно просмотра, так как у нее есть некоторые возможности масштабирования/растяжения.

Я играл около пары часов, но я не могу заставить его работать на 100%.

Это мой XAML сейчас:

<UserControl.Resources>

<Style x:Key="MyItemContainerStyle" TargetType="ListViewItem">
    <Setter Property="FontFamily" Value="Segoe UI" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    <Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>

<DataTemplate x:Key="MyItemTemplate">
    <Viewbox>
        <Border CornerRadius="3" 
        BorderBrush="Black"  
        BorderThickness="1">
            <Grid Background="Blue" MinHeight="50" MinWidth="50">
                <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">X</TextBlock>
            </Grid>
        </Border>
    </Viewbox>
</DataTemplate>

<ItemsPanelTemplate x:Key="MyItemsPanelTemplate">
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
    </StackPanel>
</ItemsPanelTemplate>

</UserControl.Resources>

<Grid Background="White">
    <GridView x:Name="MyGrid"
      UseLayoutRounding="True"
      ItemTemplate="{StaticResource MyItemTemplate}"
      ItemsPanel="{StaticResource MyItemsPanelTemplate}"
      ItemContainerStyle="{StaticResource MyItemContainerStyle}"
      ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled">
    </GridView>
</Grid>

Это производит этот вывод:

output2

Сейчас вроде вытягивается в квадрат, но вытягивается за пределы экрана. Я также запустил этот пример с несколькими разрешениями и размерами экрана, и он показывает один и тот же результат, что означает, что он правильно масштабируется.

Помощь приветствуется.

Спасибо!


person Wilco    schedule 29.03.2012    source источник


Ответы (1)


Ваша закомментированная привязка близка к тому, что может работать - только вам нужно будет привязаться к ActualWidth:

<Setter Property="Height" Value="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" />

В целом, я бы предложил использовать жестко закодированные значения - они упрощают компоновку ЦП, легче детерминистически проектировать и будут масштабироваться Windows, когда этого потребуют размер экрана и разрешение. Если вам нужен больший контроль над этим, вы можете привязать ширину и высоту к одному и тому же значению из модели представления, которую вы меняете в зависимости от необходимости, или написать преобразователь, который будет преобразовывать жестко закодированное значение ширины/высоты в фактическое значение в зависимости от обнаруженного экрана. размер/разрешение или настройки.

person Filip Skakun    schedule 30.03.2012
comment
Спасибо за быстрый ответ. Однако привязка свойства к высоте не будет работать ни с шириной, ни с фактической шириной (поэтому она закомментирована). Windows 8 изменит размер элементов в соответствии с заданным разрешением, но не изменит их размер, если я получу больший экран (с тем же разрешением). Для меня это логично, поскольку, если я укажу, что мои квадраты должны быть 50x50 пикселей, они останутся неизменными независимо от размера экрана, поскольку общее количество пикселей одинаково. Если вы запустите встроенный симулятор планшета в VS11, вы увидите это. ........ - person Wilco; 30.03.2012
comment
Я мог бы сохранить свои значения высоты и ширины в ViewModel и иметь преобразователь, который преобразует эти значения по мере необходимости в зависимости от размера экрана. Но это то, чего я пытаюсь избежать. Во-первых, мне не нравится иметь логику графического интерфейса в моих ViewModels (она принадлежит представлению). Во-вторых, к скольким размерам экрана я должен адаптироваться? Это будет грязный конвертер. Все, что я хочу, это чтобы мои квадраты расширялись настолько, насколько они могут. И может кто-нибудь объяснить мне, почему они бывают прямоугольной формы? Это встроенный стиль для GridView? Я думал, они хоть по экрану растянутся? Что их сдерживает? - person Wilco; 30.03.2012
comment
Вам не нужно иметь входные данные преобразователя в виртуальной машине, вы можете указать их явно в XAML. - person Filip Skakun; 30.03.2012
comment
Разве не было бы по-прежнему много настроек для разных размеров экрана и что-то, что нужно было бы поддерживать. Я бы предпочел иметь что-то, что работает без этого. - person Wilco; 30.03.2012
comment
Что ж, вам придется либо позволить WinRT масштабировать все за вас, либо попытаться переопределить его своим собственным подходом... Вам, вероятно, следует прочитать это: blogs.msdn.com/b/b8/archive/2012/03/21/ - person Filip Skakun; 31.03.2012