Xaml 在样式中设置网格行定义/列定义特性

Xaml 在样式中设置网格行定义/列定义特性,xaml,xamarin.forms,xamarin.forms-styles,Xaml,Xamarin.forms,Xamarin.forms Styles,假设有两个或多个轴网共享相同的结构(行/列计数和属性相等) 是否可以创建样式并设置行定义/列定义 我试过了。但当应用程序尝试解析xaml时,我会遇到此异常: Xamarin.Forms.Xaml.XamlParseException:位置14:9。属性值为null或不可IEnumerable 我的源代码: <StackLayout> <StackLayout.Resources> <ResourceDictionary>

假设有两个或多个轴网共享相同的结构(行/列计数和属性相等)

是否可以创建样式并设置行定义/列定义

我试过了。但当应用程序尝试解析xaml时,我会遇到此异常:

Xamarin.Forms.Xaml.XamlParseException:位置14:9。属性值为null或不可IEnumerable

我的源代码:

<StackLayout>
    <StackLayout.Resources>
        <ResourceDictionary>
            <Style TargetType="Grid">
                <Setter Property="RowDefinitions">
                    <Setter.Value>
                        <RowDefinition />
                        <RowDefinition />
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </StackLayout.Resources>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #1) Row #1" />
        <Label Grid.Row="1" Text="(Grid #1) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #2) Row #1" />
        <Label Grid.Row="1" Text="(Grid #2) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #3) Row #1" />
        <Label Grid.Row="1" Text="(Grid #3) Row #2" />
    </Grid>
</StackLayout>


例外情况中的位置14:9指的是第一个
标记。

不,你不能,我认为你不应该

定义网格不是关于样式,而是关于布局


从Xamarin.Forms版本3开始,将引入更多类似CSS的样式功能。也许你可以像HTML/CSS那样设计网格样式。但是对于实现什么以及如何实现,我们知之甚少。

您不能在样式中定义
RowDefinition
ColumnDefinition
,但可以将它们创建为可重用资源。我想这就是你要找的。这样定义一个
ColumnDefinitionCollection
和一个
RowDefinitionCollection
允许您将它们与许多网格一起重用,以创建一致的外观

<ResourceDictionary>
    <ColumnDefinitionCollection
        x:Key="MyColumnDefinitionCollection">
        <ColumnDefinition
            Width="50" />
        <ColumnDefinition
            Width="100" />
        <ColumnDefinition
            Width="150" />
    </ColumnDefinitionCollection>
    <RowDefinitionCollection
        x:Key="MyRowDefinitionCollection">
        <RowDefinition
            Height="50" />
        <RowDefinition
            Height="50" />
        <RowDefinition
            Height="100" />
        <RowDefinition
            Height="100" />
    </RowDefinitionCollection>
</ResourceDictionary>


您可以创建从网格派生的类

public class MyGrid : Grid
设置它,然后在xamls中的任意位置使用

<local:MyGrid> 


正如j.f所提到的,它被称为用户控制,多亏了@j.f.,我找到了解决方案。我把他的想法和我的结合起来,结果如下:

诀窍是将声明添加到单独的资源中,并在样式中引用它

<StackLayout>
    <StackLayout.Resources>
        <ResourceDictionary>
            <RowDefinitionCollection x:Key="MyRowDefinitionCollection">
                <RowDefinition />
                <RowDefinition />
            </RowDefinitionCollection>

            <Style TargetType="Grid">
                <Setter Property="RowDefinitions" Value="{StaticResource MyRowDefinitionCollection}" />
            </Style>
        </ResourceDictionary>
    </StackLayout.Resources>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #1) Row #1" />
        <Label Grid.Row="1" Text="(Grid #1) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #2) Row #1" />
        <Label Grid.Row="1" Text="(Grid #2) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #3) Row #1" />
        <Label Grid.Row="1" Text="(Grid #3) Row #2" />
    </Grid>
</StackLayout>

我找到了一个更好、更简单的解决方案。答案是在行定义标记周围添加行定义集合标记

像这样:

<StackLayout>
    <StackLayout.Resources>
        <ResourceDictionary>
            <Style TargetType="Grid">
                <Setter Property="RowDefinitions">
                    <Setter.Value>
                        <RowDefinitionCollection>
                            <RowDefinition />
                            <RowDefinition />
                        </RowDefinitionCollection>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </StackLayout.Resources>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #1) Row #1" />
        <Label Grid.Row="1" Text="(Grid #1) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #2) Row #1" />
        <Label Grid.Row="1" Text="(Grid #2) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #3) Row #1" />
        <Label Grid.Row="1" Text="(Grid #3) Row #2" />
    </Grid>
</StackLayout>


Hi Gerald Versluis,感谢您的快速回复。但如果可能的话,那就太好了。因为就像一种方法一样,你可以在一个地方修改代码,它会在多个地方生效。这是我的意见。也许创建一个自定义控件可以解决这个问题。@jf提供了一个很好的建议,或者您可以创建一个从网格派生的类,设置所有内容,然后在任何地方使用它。好吧,我也会把这个作为答案:——)好答案!我在Android和Windows中努力制作两个宽度略有不同的列,这个答案给了我解决方案。刚刚用定义了资源,并且工作得很好!似乎对我不起作用,我得到了错误:
类型“ColumnDefinitionCollection”不包括任何可访问的构造函数
属性“ColumnDefinitions”没有可访问的setter。
@Alfie,我只是再次尝试了一下,它似乎对我来说仍然很好。我建议创建另一个问题,包括如何重现您的问题的步骤。我认为这不适合OP,因为它不能跨不同的XAML文件重用。但我可能错了,他是最棒的。。。
<StackLayout>
    <StackLayout.Resources>
        <ResourceDictionary>
            <Style TargetType="Grid">
                <Setter Property="RowDefinitions">
                    <Setter.Value>
                        <RowDefinitionCollection>
                            <RowDefinition />
                            <RowDefinition />
                        </RowDefinitionCollection>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </StackLayout.Resources>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #1) Row #1" />
        <Label Grid.Row="1" Text="(Grid #1) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #2) Row #1" />
        <Label Grid.Row="1" Text="(Grid #2) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #3) Row #1" />
        <Label Grid.Row="1" Text="(Grid #3) Row #2" />
    </Grid>
</StackLayout>