在 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>
我正在尝试使用 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>