web-dev-qa-db-ja.com

2列のグリッドビュー、塗り幅

私が達成したい結果は、2つの列があり、幅が等しいリストである非常に単純なものです。 Windows Phone 7/8では、これはListBoxWrapPanelとしてItemsPanelとして使用し、ItemWidthを240(画面の幅として)に設定することで簡単に実現できます。は480でした)。

今、私はユニバーサルアプリを書いていますが、ここでの問題は、画面の幅が480であることが保証されていないため(電話の場合でも)、ItemWidthを設定できないためです画面の幅いっぱいにしたい。次のXAMLを使用して、ほぼ望ましい効果を得ることができました。

<GridView ItemsSource="{Binding Results}" Margin="12">
    <GridView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Image Source="{Binding SampleImage}" />
            </Grid>
        </DataTemplate>
    </GridView.ItemTemplate>

    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapGrid MaximumRowsOrColumns="2" Orientation="Horizontal" HorizontalChildrenAlignment="Stretch" VerticalChildrenAlignment="Stretch">
            </WrapGrid>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
</GridView>

次の結果が得られます。 enter image description here

見てわかるように、同じ幅の2つの列が正常に提供されますが、GridView.ItemTemlateGridは各列の幅全体を埋めません。 GridGridViewの両方にHorizontalAlignment="Stretch"を設定してみましたが、成功しませんでした。誰もがこれについてこれについて何か考えがありますか?

13
Johan Falk

あなたはこれを試すことができます:

<GridView.ItemContainerStyle>
    <Style
        TargetType="GridViewItem">
        <Setter
            Property="HorizontalAlignment"
            Value="Stretch" />
        <Setter
            Property="VerticalAlignment"
            Value="Stretch" />
    </Style>
 </GridView.ItemContainerStyle>

もう1つ試すことができるのは、ItemWidthItemHeightイベントを取得するたびに、手動でSizeChanged/GridViewを設定することです。

なんらかの理由で上記の方法が機能しない場合は、以下の手順を実行して、Valueイベントの両方のDoubleViewModelリソースのSizeChangedを更新することもできます。

<UserControl.Resources>
    <viewModels:DoubleViewModel
        x:Key="ItemWidth"
        Value="120" />
    <viewModels:DoubleViewModel
        x:Key="ItemHeight"
        Value="120" />
</UserControl.Resources>

...

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <local:YourItemTemplateControl
            Width="{Binding Value, Source={StaticResource ItemWidth}}"
            Height="{Binding Value, Source={StaticResource ItemHeight}}" />
    </DataTemplate>
</ItemsControl.ItemTemplate>

DoubleViewModelは次のとおりです。

public class DoubleViewModel : BindableBase
{
    #region Value
    /// <summary>
    /// Backing field for the Value property.
    /// </summary>
    private double value;

    /// <summary>
    /// Gets or sets a value indicating the value.
    /// </summary>
    public double Value
    {
        get { return this.value; }
        set { this.SetProperty(ref this.value, value); }
    }
    #endregion
}
7
Filip Skakun

私の解決策は:

<GridView ItemsSource="{Binding Results}" Margin="12"
                       SizeChanged="GridView_SizeChanged"
                       x:Name="MyGridView">
<GridView.ItemTemplate>
    <DataTemplate>
        <Grid>
            <Image Source="{Binding SampleImage}" />
        </Grid>
    </DataTemplate>
</GridView.ItemTemplate>

<GridView.ItemContainerStyle>
            <Style TargetType="GridViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                <Setter Property="VerticalAlignment" Value="Stretch"/>
            </Style>
</GridView.ItemContainerStyle>
</GridView>

コードビハインド:

private void GridView_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        var panel = (ItemsWrapGrid)MyGridView.ItemsPanelRoot;
        panel.ItemWidth =panel.ItemHeight= e.NewSize.Width / 2;
    }
14
Ganesh Cauda

私が使用したソリューションはフィリップスカカンズの提案に基づいていましたが、この動作で再利用可能なユーザーコントロールを作成することにより、わずかに異なる実装を行いました。ユーザーコントロールには、(特に)ColumnsおよびItemsSourceプロパティがあります。 ItemWidthの幅の代わりにItemsWrapGridItemTemplateを変更し、SizeChangedイベントハンドラーで直接変更します。

これを機能させるには、ItemsWrapGridの代わりにWrapGridを使用する必要もありました。最終的なユーザーコントロールのXAML:

<UserControl
    x:Class="MyProject.CustomControls.ColumnGridView"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    x:Name="ControlRoot">

    <Grid DataContext="{Binding ElementName=ControlRoot}">
        <GridView ItemsSource="{Binding ItemsSource}" ItemTemplate="{Binding ItemTemplate}">
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <ItemsWrapGrid Orientation="Horizontal" SizeChanged="ItemsWrapGrid_SizeChanged" />
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
        </GridView>
    </Grid>
</UserControl>

そして、分離コードについて:

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace MyProject.CustomControls
{
    public sealed partial class ColumnGridView : UserControl
    {
        public static readonly DependencyProperty ItemTemplateProperty =
            DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(ColumnGridView), new PropertyMetadata(null));

        public DataTemplate ItemTemplate
        {
            get { return (DataTemplate)GetValue(ItemTemplateProperty); }
            set { SetValue(ItemTemplateProperty, value); }
        }

        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(object), typeof(ColumnGridView), new PropertyMetadata(null));

        public object ItemsSource
        {
            get { return (object)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        public static readonly DependencyProperty ColumnsProperty =
            DependencyProperty.Register("Columns", typeof(int), typeof(ColumnGridView), new PropertyMetadata(1));

        public int Columns
        {
            get { return (int)GetValue(ColumnsProperty); }
            set
            {
                if (value <= 0) throw new ArgumentOutOfRangeException("Columns must be greater than 0");
                SetValue(ColumnsProperty, value);
            }
        }

        public ColumnGridView()
        {
            this.InitializeComponent();
        }

        private void ItemsWrapGrid_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            ItemsWrapGrid itemsWrapGrid = sender as ItemsWrapGrid;
            if (itemsWrapGrid != null)
            {
                itemsWrapGrid.ItemWidth = e.NewSize.Width / Columns;
            }
        }
    }
}
6
Johan Falk

次のように、Item Widthを親ActualWidthにバインドするだけで、非常によく似た問題を解決できました。

<ListView Name="allDevicesListView" d:DataContext="{d:DesignData /SampleData/VeraServerSampleData.xaml}" ItemsSource="{Binding Devices}">
<ListView.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal" Width="{Binding ElementName=allDevicesListView, Path=ActualWidth}">
            <Grid Width="{Binding ElementName=allDevicesListView, Path=ActualWidth}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="2*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding Name}" FontSize="24" Grid.Column="0" Margin="0,0,14.333,0" />
                <local:VeraDeviceControl VeraDeviceCategory="DimmableLight" Width="auto" Grid.Column="1"/>
            </Grid>
        </StackPanel>
    </DataTemplate>
</ListView.ItemTemplate>
4
Vinicius

または、WrapGridのLoaded-Eventを使用して、少なくともItemWidthを設定することもできます

XAML

<Grid Background="LightGreen">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>

    <Grid Grid.Row="0" Grid.Column="0" Name="MyGrid" Background="Red">

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="60" />
            <ColumnDefinition Width="60" />
            <ColumnDefinition Width="60" />
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" />
        <TextBlock Grid.Column="1" Text="I.O" />
        <TextBlock Grid.Column="2" Text="N.V" />
        <TextBlock Grid.Column="3" Text="n.I.O" />
    </Grid>

    <Grid Grid.Row="0" Grid.Column="1" Background="Aqua">

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="60" />
            <ColumnDefinition Width="60" />
            <ColumnDefinition Width="60" />
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" />
        <TextBlock Grid.Column="1" Text="I.O" />
        <TextBlock Grid.Column="2" Text="N.V" />
        <TextBlock Grid.Column="3" Text="n.I.O" />
    </Grid>

    <GridView Grid.Row="1"  Grid.ColumnSpan="2"
              Background="LightBlue"
              HorizontalAlignment="Stretch"
              ItemsSource="{Binding Details}"
              ItemContainerStyle="{StaticResource GridViewItemStyleIOhneHover}"
              ItemTemplateSelector="{StaticResource MyProtokollElementDataTemplateSelector}">
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapGrid Orientation="Horizontal"
                          HorizontalAlignment="Stretch"
                          MaximumRowsOrColumns="2"
                          HorizontalChildrenAlignment="Stretch"
                          VerticalChildrenAlignment="Stretch" Loaded="MyWrapGrid_Loaded">
                </WrapGrid>
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
    </GridView>
</Grid>

分離コード

    private void MyWrapGrid_Loaded(object sender, RoutedEventArgs e)
    {
        var wg = sender as WrapGrid;
        wg.ItemWidth = MyGrid.ActualWidth;
    }

enter image description here

0
WiiMaxx