ListView
が必須ではなく、テンプレートサポートで反復可能なコントロールが必要な場合は、ItemsControl
を使用できます。パネルとしてStackLayout
を使用しているため、必要な高さにしか拡大しません。だから、あなたはそれの高さを計算する必要はありません。 ご注意くださいItemsControl
には非常に基本的な仮想化の動作(リサイクル)があります。そのため、多くのアイテムがある場合は、仮想化をサポートするようにコントロールを変更する必要があります。
第二に、あなたは自動的に下のコンテンツのサイズごとにAuto
またはStar
に2つ目のRowDefinition
を設定するGrid
を拡張することができます。つまり、デフォルトではAuto
のままにしますが、コンテンツサイズがビューポートの高さの50%を超える場合は、RowDefinition
をStar
にリセットしてください。例えばのために、あなたは、カスタムSplitterGrid
作成することができます。
public class SplitterGrid : Grid
{
public SplitterGrid()
{
RowDefinitions = new RowDefinitionCollection()
{
new RowDefinition { Height = GridLength.Star },
new RowDefinition { Height = GridLength.Auto }
};
}
void Content2_SizeChanged(object sender, EventArgs e)
{
if (Height == 0 && Width == 0)
return;
Content2.SizeChanged -= Content2_SizeChanged;
if (Content2.Height > Height/2)
RowDefinitions[1].Height = GridLength.Star;
else
RowDefinitions[1].Height = GridLength.Auto;
}
public static readonly BindableProperty Content1Property =
BindableProperty.Create(
"Content1", typeof(View), typeof(SplitterGrid),
defaultValue: null, propertyChanged: OnContent1Changed);
public View Content1
{
get { return (View)GetValue(Content1Property); }
set { SetValue(Content1Property, value); }
}
private static void OnContent1Changed(BindableObject bindable, object oldValue, object newValue)
{
((SplitterGrid)bindable).OnContent1ChangedImpl((View)oldValue, (View)newValue);
}
void OnContent1ChangedImpl(View oldValue, View newValue)
{
if (oldValue == null)
Children.Add(Content1);
}
public static readonly BindableProperty Content2Property =
BindableProperty.Create(
"Content2", typeof(View), typeof(SplitterGrid),
defaultValue: null, propertyChanged: OnContent2Changed);
public View Content2
{
get { return (View)GetValue(Content2Property); }
set { SetValue(Content2Property, value); }
}
private static void OnContent2Changed(BindableObject bindable, object oldValue, object newValue)
{
((SplitterGrid)bindable).OnContent2ChangedImpl((View)oldValue, (View)newValue);
}
void OnContent2ChangedImpl(View oldValue, View newValue)
{
if (oldValue == null)
{
Children.Add(Content2);
Content2.SizeChanged += Content2_SizeChanged;
Grid.SetRow(Content2, 1);
}
else
Content2.SizeChanged -= Content2_SizeChanged;
}
}
をそして、使い方は次のようになります動作するようには思えない残念ながら
<local:SplitterGrid Margin="0,20,0,0">
<local:SplitterGrid.Content1>
<ContentView Padding="10" BackgroundColor="#E4E4E4">
<Label Text="This page contains about 3 items." />
</ContentView>
</local:SplitterGrid.Content1>
<local:SplitterGrid.Content2>
<ScrollView VerticalOptions="End">
<local:ItemsControl>
<local:ItemsControl.ItemTemplate>
<DataTemplate>
<Label FontAttributes="Bold" FontSize="40" Text="{Binding .}" />
</DataTemplate>
</local:ItemsControl.ItemTemplate>
<local:ItemsControl.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
<x:String>Item 3</x:String>
</x:Array>
</local:ItemsControl.ItemsSource>
</local:ItemsControl>
</ScrollView>
</local:SplitterGrid.Content2>
</local:SplitterGrid>
![enter image description here](https://i.stack.imgur.com/GfOP2.gif)
出典
2017-08-25 00:37:16
Ada
ありがとうございます、ItemsControlはすばらしい働きをしています([リサイクルのバグ](https://github.com/xamarinhq/xamu-infrastructure/pull/7)は保存しています)。 – cmeeren
私はそれが簡単に修正できるはずだと信じています。 ItemsSource変更リスナーで明確なメソッドを追加する(新しいコレクションの数が以前より少ない場合) – Ada
はい、それを修正するPRにリンクしました。 – cmeeren