Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xaml 如何使3列Xamarin.Forms FlexLayout具有扩展的中心列和可变宽度的左/右列?_Xaml_Xamarin_Xamarin.forms - Fatal编程技术网

Xaml 如何使3列Xamarin.Forms FlexLayout具有扩展的中心列和可变宽度的左/右列?

Xaml 如何使3列Xamarin.Forms FlexLayout具有扩展的中心列和可变宽度的左/右列?,xaml,xamarin,xamarin.forms,Xaml,Xamarin,Xamarin.forms,我正在尝试在Xamarin中创建一个FlexLayout。表单允许我将左右列设置为可变宽度,并使中间列(及其内容)填充剩余空间并在屏幕上居中 这是我当前的代码,这是它产生的代码。请注意,蓝色的“居中文本”在其堆栈布局中居中,但堆栈布局在屏幕上不居中,因为左右列的宽度不同 FlexLayout是一个很好的选择,还是应该使用Grid或其他什么?理想情况下,每列都将展开以适应其内容,中间列的内容将在屏幕上居中 请注意,每列的内容都是动态的,因此左右列的宽度也是动态的 谢谢大家! 代码: <Fle

我正在尝试在Xamarin中创建一个
FlexLayout
。表单允许我将左右列设置为可变宽度,并使中间列(及其内容)填充剩余空间并在屏幕上居中

这是我当前的代码,这是它产生的代码。请注意,蓝色的“居中文本”在其
堆栈布局
中居中,但
堆栈布局
在屏幕上不居中,因为左右列的宽度不同

FlexLayout
是一个很好的选择,还是应该使用
Grid
或其他什么?理想情况下,每列都将展开以适应其内容,中间列的内容将在屏幕上居中

请注意,每列的内容都是动态的,因此左右列的宽度也是动态的

谢谢大家!

代码:

<FlexLayout x:Name="titleBar" 
            MinimumHeightRequest="40"
            Padding="10"
            JustifyContent="SpaceBetween"
            AlignItems="Center"
            AlignContent="Center">
    <StackLayout x:Name="leftActionButton"
                 VerticalOptions="Center"
                 BackgroundColor="Red"
                 Orientation="Horizontal">
        <Image x:Name="leftActionImg" 
               Margin="0, 0, 5, 0"
               HeightRequest="40"
               VerticalOptions="Center" />
        <Label x:Name="leftActionLabel" 
               VerticalOptions="Center" />
    </StackLayout>

    <StackLayout VerticalOptions="Center"
                 BackgroundColor="Blue"
                 FlexLayout.Grow="1"
                 FlexLayout.Shrink="0">
        <Label x:Name="title"
               HorizontalTextAlignment="Center"/>
    </StackLayout>

    <StackLayout x:Name="rightActionButton"
                 BackgroundColor="Yellow"
                 VerticalOptions="Center"
                 Orientation="Horizontal">
        <Label x:Name="rightActionLabel" 
               VerticalOptions="Center"
               HorizontalOptions="End"
               HorizontalTextAlignment="End" />
        <Image x:Name="rightActionImg"
               HeightRequest="40"
               VerticalOptions="Center"
               HorizontalOptions="End" />
    </StackLayout>
</FlexLayout>

结果:

<FlexLayout x:Name="titleBar" 
            MinimumHeightRequest="40"
            Padding="10"
            JustifyContent="SpaceBetween"
            AlignItems="Center"
            AlignContent="Center">
    <StackLayout x:Name="leftActionButton"
                 VerticalOptions="Center"
                 BackgroundColor="Red"
                 Orientation="Horizontal">
        <Image x:Name="leftActionImg" 
               Margin="0, 0, 5, 0"
               HeightRequest="40"
               VerticalOptions="Center" />
        <Label x:Name="leftActionLabel" 
               VerticalOptions="Center" />
    </StackLayout>

    <StackLayout VerticalOptions="Center"
                 BackgroundColor="Blue"
                 FlexLayout.Grow="1"
                 FlexLayout.Shrink="0">
        <Label x:Name="title"
               HorizontalTextAlignment="Center"/>
    </StackLayout>

    <StackLayout x:Name="rightActionButton"
                 BackgroundColor="Yellow"
                 VerticalOptions="Center"
                 Orientation="Horizontal">
        <Label x:Name="rightActionLabel" 
               VerticalOptions="Center"
               HorizontalOptions="End"
               HorizontalTextAlignment="End" />
        <Image x:Name="rightActionImg"
               HeightRequest="40"
               VerticalOptions="Center"
               HorizontalOptions="End" />
    </StackLayout>
</FlexLayout>

我使用两列网格,并使用网格覆盖顶部的“中心”列。ColumnSpan=“2”实现了这一点

我意识到中间的内容有可能与左右内容重叠,但如果这是我能做到的最好的话,我可以绕过这个限制。不过,还是欢迎其他更有力的建议

<Grid x:Name="titleBar" 
      MinimumHeightRequest="40"
      Padding="10"
      HorizontalOptions="FillAndExpand">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <StackLayout x:Name="leftActionButton"
                 VerticalOptions="Center"
                 Orientation="Horizontal"
                 HorizontalOptions="Start"
                 Grid.Column="0">
        <Image x:Name="leftActionImg" 
               Margin="0, 0, 5, 0"
               HeightRequest="40"
               VerticalOptions="Center" />
        <Label x:Name="leftActionLabel" 
               VerticalOptions="Center" />
    </StackLayout>

    <StackLayout x:Name="rightActionButton"
                 VerticalOptions="Center"
                 HorizontalOptions="End"
                 Orientation="Horizontal"
                 Grid.Column="1">
        <Label x:Name="rightActionLabel" 
               VerticalOptions="Center"
               HorizontalOptions="End"
               HorizontalTextAlignment="End" />
        <Image x:Name="rightActionImg"
               HeightRequest="40"
               VerticalOptions="Center"
               HorizontalOptions="End" />
    </StackLayout>

    <StackLayout VerticalOptions="Center"
                 HorizontalOptions="CenterAndExpand"
                 Grid.Column="0"
                 Grid.ColumnSpan="2">
        <Label x:Name="title"
               HorizontalTextAlignment="Center"/>
    </StackLayout>
</Grid>

我最近也遇到了同样的问题。所以我花了一天的时间来寻找解决方案。结果是幻灭,我不认为这是一个合适的解决方案。我在这里发表我的想法,因为我在网上找不到类似的东西

  • 我创建了一个负责平衡所有三列的组件:它订阅左右列的宽度变化,并将相对差异传播到中间列
  • 中柱通过应用填充将相对差异作为校正
MainPage:在参考资料部分,您可以看到我正在声明ColumnBalancer的一个实例。稍后,我将宽度更改订阅给ColumnBalancer,这样ColumnBalancer就可以在非常左和非常右的列(实际上是内容)更改时知道它。只要宽度值发生更改,就会从同一ColumnBalancer实例检索PaddingOffset绑定

   <ContentPage
        x:Class="App7863.MainPage"
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:d="http://xamarin.com/schemas/2014/forms/design"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:cb="clr-namespace:ColumnBalancing"
        mc:Ignorable="d">

        <ContentPage.Resources>
            <ResourceDictionary>
                <cb:ColumnBalancer x:Key="ColumnBalancer" x:Name="ColumnBalancer" />
            </ResourceDictionary>
        </ContentPage.Resources>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

            <!--  Header  -->
            <Grid
                Grid.Row="0"
                Padding="10"
                BackgroundColor="LightGray">
                <Grid.RowDefinitions>
                    <RowDefinition Height="39" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>

                <!--  Navigate Back Button  -->
                <Label
                    Grid.Column="0"
                    Width="{Binding Source={x:Reference ColumnBalancer}, Path=ReferenceWidthLeft}"
                    Text="&lt;"
                    FontSize="20"
                    BackgroundColor="Magenta"
                    WidthRequest="39"
                    HeightRequest="39"
                    VerticalOptions="CenterAndExpand"
                    VerticalTextAlignment="Center"
                    HorizontalOptions="CenterAndExpand"
                    HorizontalTextAlignment="Center" />

                <!--  Page Title  -->
                <StackLayout
                    Grid.Column="1"
                    Margin="0"
                    Padding="{Binding Source={x:Reference ColumnBalancer}, Path=PaddingOffset}"
                    BackgroundColor="LightYellow"
                    Spacing="0">
                    <Label
                        Text="Center Title"
                        FontSize="20"
                        BackgroundColor="Magenta"
                        HeightRequest="39"
                        VerticalOptions="CenterAndExpand"
                        VerticalTextAlignment="Center"
                        HorizontalOptions="CenterAndExpand"
                        HorizontalTextAlignment="Center"
                        LineBreakMode="TailTruncation" />
                </StackLayout>

                <!--  Toolbar Items  -->
                <StackLayout
                    Grid.Column="2"
                    Width="{Binding Source={x:Reference ColumnBalancer}, Path=ReferenceWidthRight}"
                    Margin="0"
                    Padding="0"
                    BackgroundColor="LightGreen"
                    Orientation="Horizontal"
                    Spacing="6">
                    <Label
                        x:Name="ToolbarT1"
                        Text="T1"
                        FontSize="20"
                        BackgroundColor="Green"
                        WidthRequest="39"
                        HeightRequest="39"
                        VerticalOptions="CenterAndExpand"
                        VerticalTextAlignment="Center"
                        HorizontalOptions="CenterAndExpand"
                        HorizontalTextAlignment="Center"
                        IsVisible="False" />
                    <Label
                        x:Name="ToolbarT2"
                        Text="T2"
                        FontSize="20"
                        BackgroundColor="Green"
                        WidthRequest="39"
                        HeightRequest="39"
                        VerticalOptions="CenterAndExpand"
                        VerticalTextAlignment="Center"
                        HorizontalOptions="CenterAndExpand"
                        HorizontalTextAlignment="Center"
                        IsVisible="False" />
                </StackLayout>

                <Label
                    Grid.Row="2"
                    Grid.ColumnSpan="3"
                    Text="Subtitle with more info"
                    FontSize="20"
                    BackgroundColor="LightBlue"
                    HeightRequest="39"
                    VerticalOptions="CenterAndExpand"
                    VerticalTextAlignment="Center"
                    HorizontalOptions="StartAndExpand"
                    HorizontalTextAlignment="Start" />
            </Grid>

            <!--  Content  -->
            <Grid
                Grid.Row="1"
                Padding="40"
                BackgroundColor="LightCoral">
                <StackLayout BackgroundColor="LightBlue">
                    <Button Text="Toogle T1" Clicked="Button_ToogleT1" />
                    <Button Text="Toogle T2" Clicked="Button_ToogleT2" />
                </StackLayout>
            </Grid>
        </Grid>

    </ContentPage>

ColumnBalancer:公开ReferenceWidthLeft和ReferenceWidthRight,这两个参数分别从左侧和右侧获取宽度值。右栏内容。只要ReferenceWidth*属性发生更改,就会设置一个新的填充偏移

 public class ColumnBalancer : BindableObject
        {
            public static readonly BindableProperty PaddingOffsetProperty = BindableProperty.Create(
                nameof(PaddingOffset),
                typeof(Thickness),
                typeof(ColumnBalancer),
                default(Thickness),
                BindingMode.OneWay);

            public Thickness PaddingOffset
            {
                get => (Thickness)this.GetValue(PaddingOffsetProperty);
                set => this.SetValue(PaddingOffsetProperty, value);
            }

            public static readonly BindableProperty ReferenceWidthRightProperty = BindableProperty.Create(
                nameof(ReferenceWidthRight),
                typeof(double),
                typeof(ColumnBalancer),
                default(double),
                BindingMode.OneWayToSource,
                null,
                OnReferenceWidthRightPropertyChanged);

            public double ReferenceWidthRight
            {
                get => (double)this.GetValue(ReferenceWidthRightProperty);
                set => this.SetValue(ReferenceWidthRightProperty, value);
            }

            public static readonly BindableProperty ReferenceWidthLeftProperty = BindableProperty.Create(
                nameof(ReferenceWidthLeft),
                typeof(double),
                typeof(ColumnBalancer),
                default(double),
                BindingMode.OneWayToSource,
                null,
                OnReferenceWidthLeftPropertyChanged);

            public double ReferenceWidthLeft
            {
                get => (double)this.GetValue(ReferenceWidthLeftProperty);
                set => this.SetValue(ReferenceWidthLeftProperty, value);
            }

            private static void OnReferenceWidthLeftPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
            {
                if (!(bindable is ColumnBalancer columnBalancer) || !(newvalue is double newLeftValue && newLeftValue >= 0))
                {
                    return;
                }

                UpdatePaddingOffset(columnBalancer, newLeftValue, columnBalancer.ReferenceWidthRight);
            }

            private static void OnReferenceWidthRightPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
            {
                if (!(bindable is ColumnBalancer columnBalancer) || !(newvalue is double newRightValue && newRightValue >= 0))
                {
                    return;
                }

                UpdatePaddingOffset(columnBalancer, columnBalancer.ReferenceWidthLeft, newRightValue);
            }

            private static void UpdatePaddingOffset(ColumnBalancer columnBalancer, double left, double right)
            {
                if (left < 0)
                {
                    left = 0;
                }

                if (right < 0)
                {
                    right = 0;
                }

                var relativePadding = Math.Abs(left - right);
                if (right > left)
                {
                    columnBalancer.PaddingOffset = new Thickness(relativePadding, 0, 0, 0);
                }
                else
                {
                    columnBalancer.PaddingOffset = new Thickness(0, 0, relativePadding, 0);
                }
            }
        }
公共类列平衡器:BindableObject
{
公共静态只读BindableProperty PaddingOffsetProperty=BindableProperty.Create(
名称(填充偏移),
类型(厚度),
类型(柱形平衡器),
默认值(厚度),
绑定模式(单向);
公共厚度填充补偿
{
get=>(厚度)this.GetValue(PaddingOffsetProperty);
set=>this.SetValue(PaddingOffsetProperty,value);
}
公共静态只读BindableProperty引用WidthRightProperty=BindableProperty.Create(
名称(参考宽度右侧),
类型(双),
类型(柱形平衡器),
违约(双倍),
BindingMode.OneWayToSource,
无效的
OnReferenceWidthRightPropertyChanged);
公共双重参照权
{
get=>(双精度)this.GetValue(ReferenceWidthRightProperty);
set=>this.SetValue(ReferenceWidthRightProperty,value);
}
公共静态只读BindableProperty引用WidthLeftProperty=BindableProperty.Create(
名称(参考宽度左),
类型(双),
类型(柱形平衡器),
违约(双倍),
BindingMode.OneWayToSource,
无效的
OnReferenceWidthLeftPropertyChanged);
公共双参考宽度左
{
get=>(双精度)this.GetValue(ReferenceWidthLeftProperty);
set=>this.SetValue(ReferenceWidthLeftProperty,value);
}
私有静态void OnReferenceWidthLeftPropertyChanged(BindableObject bindable、object oldvalue、object newvalue)
{
如果(!(bindable是ColumnBalancer ColumnBalancer)| |!(newvalue是双newLeftValue&&newLeftValue>=0))
{
返回;
}
UpdatePaddingOffset(columnBalancer、newLeftValue、columnBalancer.ReferenceWidthRight);
}
私有静态void OnReferenceWidthRightPropertyChanged(BindableObject bindable、object oldvalue、object newvalue)
{
如果(!(bindable是ColumnBalancer ColumnBalancer)| |!(newvalue i