理解 WidthRequest

Understanding WidthRequest

我想换WidthRequest。因此我注意到这并没有真正设置元素的 width 。相反,它是一种提议。

示例: 我将 ListView 添加为 child 到 StackLayout。我正在为 ListView 设置 WidthRequest,但结果不是我所期望的。

this.listView = new ListView
{
    ItemsSource = new List<IconMenu>
    {
        // creation of some entries
        // ...
    },
    ItemTemplate = new DataTemplate(typeof(IconMenuCell)),
    RowHeight = 44,
    // HERE is the problematic code!
    WidthRequest = 10,
};

Content = new StackLayout
{
    Orientation = StackOrientation.Horizontal,
    Children = {
        this.listView,
        this.detailView,
    },
};

这是IconMenuCell的structure/layout:

public IconMenuCell()
{
    var icon = new Image
    {
        Aspect = Aspect.AspectFit,
        WidthRequest = 40,
    };
    icon.SetBinding(Image.SourceProperty, "IconSource");

    this.textLabel = new Label {
        TextColor = Color.Gray,
        FontSize = 10,
        VerticalOptions = LayoutOptions.Center,
    };
    this.textLabel.SetBinding(Label.TextProperty, "Text");

    View = new StackLayout
    {
        Orientation = StackOrientation.Horizontal,
        Children =
        {
            icon,
            this.textLabel,
        },
    };
}

WidthRequest 设置为 10 没有意义,因为图标本身应该占用 40。但是这里我得到了整个列表视图的最小宽度。

如果我将 WidthRequest 设置为 60 或 120 没有区别。结果宽度是相同的(而不是我想要的)。

WidthRequest 在这里如何工作?我必须更改一些 LayoutOptions 吗?

WidthRequest 只是描述元素在下一个布局周期中所需的宽度。
要使其如您所愿工作,必须满足 2 个条件:
1) 请求的宽度与所有约束一致(例如 parent 的宽度)和
2) 触发布局循环。
宽度请求:https://developer.xamarin.com/api/property/Xamarin.Forms.VisualElement.WidthRequest/

但这很复杂。我建议只用网格替换堆栈布局,并将每个元素放在所需宽度的列中。
网格示例:https://developer.xamarin.com/api/type/Xamarin.Forms.Grid/

您需要指定 Horizo​​ntalOptions,例如“start”或“center”。 stackLayout 的默认 horizo​​ntalOptions 是 FillAndExpand,因此即使您指定了宽度,像 listview 这样的子元素也会填充整个可用的水平区域。这是代表 Microsoft 的错误调用,因为默认行为将 ignore/override 宽度请求。

这是一个可视化示例:我有一个选择器,我将宽度请求设置为 200,它应该占据水平方向的大约 2/3 space。

<StackLayout Padding="10">
    <Picker x:Name="pickerRanks" WidthRequest="200" />
</StackLayout>

如您所见,宽度要求为 overridden/ignored。然后如果将 Horizo​​ntalOptions 设置为“开始”...

<StackLayout Padding="10">
    <Picker x:Name="pickerRanks" WidthRequest="200" HorizontalOptions="Start"/>
</StackLayout>

宽度请求得到满足。当然,我在这里设置 .xaml 文件中的属性,我通常更喜欢这样,但您也可以像这样在 C# 中设置 Horizo​​ntalOptions

pickerRanks.HorizontalOptions = LayoutOptions.Start;