在 Xamarin.Forms 上绑定网格列宽

Binding Grid Column Width on Xamarin.Forms

我正在尝试使用 Xamarin.Forms 中的网格控件构建一个 3 列状态栏。我收到 3 个值:open、pending 和 filled。我希望列宽绑定到这些值。但是,列宽保持相等。

当前外观:

想要的外观:

这是通过将列宽中的绑定分别替换为 3*、0* 和 2* 来实现的。

XAML

<Frame HorizontalOptions="FillAndExpand" CornerRadius="10" HasShadow="False" Padding="0" IsClippedToBounds="True">
    <Grid ColumnSpacing="0" HorizontalOptions="FillAndExpand">
        <Grid.RowDefinitions>
            <RowDefinition Height="25" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="{Binding Filled, StringFormat='{0:N}*'}" />
            <ColumnDefinition Width="{Binding Pending, StringFormat='{0:N}*'}" />
            <ColumnDefinition Width="{Binding Open, StringFormat='{0:N}*'}" />
        </Grid.ColumnDefinitions>
        <BoxView Grid.Column="0" Color="#5cb85c" />
        <Label Grid.Column="0" Text="{Binding Filled}" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" />
        <BoxView Grid.Column="1" Color="#f0ad4e" />
        <Label Grid.Column="1" Text="{Binding Pending}" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" />
        <BoxView Grid.Column="2" Color="#d43f3a" />
        <Label Grid.Column="2" Text="{Binding Open}" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" />
    </Grid>
</Frame>

更新:

我根据您的建议更新了我的代码。问题是转换器没有被触发。我没有收到错误消息,也从未达到转换器中的断点。我添加了“Source={x:Reference listView}”,因为我看到一些 SO 答案表明了这一点。但是,它没有帮助。我还尝试向标签添加一个基本的双精度字符串转换器,但它也没有执行。

XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:conv="clr-namespace:MyApp.Converters" x:Class="MyApp.Views.OrgDash.PositionsPage" Title="Positions">
    <ContentPage.Resources>
        <ResourceDictionary>
            <conv:NumberToGridLengthConverter x:Key="numberToGridLengthConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <AbsoluteLayout x:Name="absLayout" VerticalOptions="FillAndExpand">
            <ListView x:Name="listView" HasUnevenRows="true" ItemTapped="OnItemTapped" HeightRequest="{Binding Path=Height, Source={x:Reference absLayout}}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Padding="10,10,10,10" Orientation="Vertical">
                                <StackLayout HorizontalOptions="StartAndExpand" Orientation="Horizontal">
                                    <Label Text="{Binding Name}" VerticalTextAlignment="Center" FontAttributes="Bold" />
                                </StackLayout>
                                <Frame HorizontalOptions="FillAndExpand" CornerRadius="10" HasShadow="False" Padding="0" IsClippedToBounds="True">
                                    <Grid ColumnSpacing="0" HorizontalOptions="FillAndExpand">
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="25" />
                                        </Grid.RowDefinitions>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="{Binding Filled, Source={x:Reference listView}, Converter={StaticResource numberToGridLengthConverter}}" />
                                            <ColumnDefinition Width="{Binding Pending, Source={x:Reference listView}, Converter={StaticResource numberToGridLengthConverter}}" />
                                            <ColumnDefinition Width="{Binding Open, Source={x:Reference listView}, Converter={StaticResource numberToGridLengthConverter}}" />
                                        </Grid.ColumnDefinitions>
                                        <BoxView Grid.Column="0" Color="#5cb85c" />
                                        <Label Grid.Column="0" Text="{Binding Filled" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" />
                                        <BoxView Grid.Column="1" Color="#f0ad4e" />
                                        <Label Grid.Column="1" Text="{Binding Pending}" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" />
                                        <BoxView Grid.Column="2" Color="#d43f3a" />
                                        <Label Grid.Column="2" Text="{Binding Open}" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" />
                                    </Grid>
                                </Frame>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <ContentView x:Name="overlay" AbsoluteLayout.LayoutBounds="0, 0, 1, 1"  AbsoluteLayout.LayoutFlags="All" IsVisible="True" BackgroundColor="#C0808080" Padding="10, 0">
                <ActivityIndicator  WidthRequest="110" HeightRequest="70" IsRunning="True" IsVisible="True" Color="Black" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
            </ContentView>
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage>

转换器Class:

using System;
using System.Globalization;
using Xamarin.Forms;

namespace MyApp.Converters
{
    public class NumberToGridLengthConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var numberValue = (double)value;
            return new GridLength(numberValue, GridUnitType.Star);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var gridLength = (GridLength)value;
            return gridLength.Value;
        }
    }
}

我猜你的绑定会导致绑定错误,你会在 Debug window 中看到这样的东西:

[0:] Binding: '3.00*' can not be converted to type 'Xamarin.Forms.GridLength'.

[0:] Binding: '0.00*' can not be converted to type 'Xamarin.Forms.GridLength'.

[0:] Binding: '2.00*' can not be converted to type 'Xamarin.Forms.GridLength'.

我会使用自定义转换器将数字值转换为 GridLength:

public class NumberToGridLengthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var numberValue = (double)value;
        return new GridLength(numberValue, GridUnitType.Star);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var gridLength = (GridLength)value;
        return gridLength.Value;
    }
}

Xaml:

<ContentPage.Resources>
    <ResourceDictionary>
        <conv:NumberToGridLengthConverter x:Key="numberToGridLengthConverter" />
    </ResourceDictionary>
</ContentPage.Resources>
...
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="{Binding Filled, Converter={StaticResource numberToGridLengthConverter}}" />
    <ColumnDefinition Width="{Binding Pending, Converter={StaticResource numberToGridLengthConverter}}" />
    <ColumnDefinition Width="{Binding Open, Converter={StaticResource numberToGridLengthConverter}}" />
</Grid.ColumnDefinitions>