问题描述
我正在构建一个均质按钮的矩形网格,其中包含要在运行时设置的动态行和列。该规范在Xamarin中。所有最新版本等 整个项目可以在这里下载:https://github.com/BicycleMark/XamSweeper 我遇到的问题是XAML的MultiBinding部分。任何评论或建议都将非常出色
我使用嵌套StackPanels来创建网格,如下所示:
我成功创建了一个MultiValueConverter,用于调整大小正确显示的按钮。我已经用单元测试测试了转换器,并且它按预期运行。 [R,C]打印在每个按钮的测试中。这些是从正确绑定的模型中提取的
我遇到的问题是将MultiBinding链接到我需要计算按钮大小的3个项目上:
每个按钮的宽度是使用这三个参数计算的
每个按钮的高度是使用这三个参数计算的
以下是描述的转换器:
public class SizeConverter : IMultiValueConverter
{
public object Convert(object[] values,Type targettype,object parameter,CultureInfo culture)
{
if (values == null || values.Length <3 || values[2] == null || values[1] == null || values[0] == null)
return 50;
int numItems = (int)values[2];
int separatorSize = (int)values[1];
double frameSize = System.Convert.Todouble(values[0]) ;
int totalSeparatorSize = (numItems - 1) * separatorSize;
int remainingArea = System.Convert.ToInt32(frameSize) - totalSeparatorSize;
return remainingArea / numItems;
}
public object[] ConvertBack(object value,Type[] targettypes,CultureInfo culture)
{
throw new NotImplementedException();
}
}
及其通过的单元测试:
[DaTarow(100,2,4)]
[DataTestMethod]
public void Test_Piece_Sizing(double frameSize,int separatorSize,int numItems)
{
var sizeConverter = new SizeConverter();
object[] values = new object[] { frameSize,separatorSize,numItems };
Assert.AreNotEqual(0,sizeConverter.Convert(values,typeof(int),null,System.Globalization.CultureInfo.CurrentCulture));
}
当前的问题是当我在Xamarin中绑定我的值时,我的转换器从XAML传递了Null 这是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:prism="http://prismlibrary.com"
prism:viewmodelLocator.Autowireviewmodel="True"
xmlns:local="clr-namespace:sweeper.Controls;assembly=sweeper"
xmlns:cvt="clr-namespace:sweeper.Views.Converters;assembly=sweeper"
x:Class="sweeper.Views.GamePage"
Title="Game"
x:Name="page">
<ContentPage.Resources>
<cvt:SizeConverter x:Key="SizeConverter" />
<cvt:CoordinateConverter x:Key="CoordinateConverter" />
</ContentPage.Resources>
<Frame BackgroundColor="DarkSeaGreen" CornerRadius="15" Padding="15">
<Grid RowDeFinitions="*,3*">
<Frame Grid.Row="0" Padding="0">
<Grid ColumnDeFinitions="*,*,*" Padding="0" >
<Frame Grid.Column="0">
<Label HorizontalOptions="Center" VerticalOptions="Center">
<Label.Text>
<MultiBinding Converter="{StaticResource CoordinateConverter}">
<Binding Path="Board.Rows" />
<Binding Path="Board.Columns" />
</MultiBinding>
</Label.Text>
</Label>
</Frame>
<Frame Grid.Column="1">
<Button Text="Ok"></Button>
</Frame>
<Frame Grid.Column="2">
<Label HorizontalOptions="Center" VerticalOptions="Center" Text="{Binding Game.Time}"/>
</Frame>
</Grid>
</Frame>
<Frame Grid.Row="1" x:Name="frameButtons" Padding="4" HasShadow="True" >
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Vertical" Spacing="4"
BindableLayout.ItemsSource="{Binding Board.RowItems}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout BindableLayout.ItemsSource="{Binding}" Orientation="Horizontal" HorizontalOptions="Center">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Frame Padding="0" HasShadow="False" BackgroundColor="LightBlue" >
<Button Text="{Binding Name}" FontSize="Body" HorizontalOptions="Center" TextColor="Navy"/>
<Frame.WidthRequest>
<MultiBinding Converter="{StaticResource SizeConverter}" >
<MultiBinding.Bindings>
<Binding Source="x:Reference frameButtons" Path="ActualWidth" />
<Binding Source="x:Reference frameButtons" Path="Padding" />
<Binding Source="x:Reference frameButtons" Path="BindingContext.Board.Columns" />
</MultiBinding.Bindings>
</MultiBinding>
</Frame.WidthRequest>
<Frame.HeightRequest>
<MultiBinding Converter="{StaticResource SizeConverter}" >
<MultiBinding.Bindings>
<Binding Source="x:Reference frameButtons" Path="ActualHeight"/>
<Binding Source="x:Reference frameButtons" Path="Padding" />
<Binding Source="x:Reference frameButtons" Path="BindingContext.Board.Rows" />
</MultiBinding.Bindings>
</MultiBinding>
</Frame.HeightRequest>
</Frame >
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</Frame>
</Grid>
</Frame>
</ContentPage>
转换器正在被调用,但是我每次都传递3个null。这是我要修复的绑定错误
整个项目可以在这里下载:https://github.com/BicycleMark/XamSweeper
解决方法
转换器正在被调用,但我每次都传递3个null。
您可以尝试将{
"Login":"Kapitan","Password":"M3030"
}
设置为BindingContext
,例如:
Frame
然后您就可以在<Frame Padding="0" HasShadow="False" BackgroundColor="LightBlue" BindingContext="{x:Reference frameButtons}">
<Button Text="{Binding Name}" FontSize="Body" HorizontalOptions="Center" TextColor="Navy" Clicked="Button_Clicked"/>
<Frame.WidthRequest>
<MultiBinding Converter="{StaticResource SizeConverter}" >
<MultiBinding.Bindings>
<Binding Path="ActualWidth" />
<Binding Path="Padding" />
<Binding Path="BindingContext.Board.Columns" />
</MultiBinding.Bindings>
</MultiBinding>
</Frame.WidthRequest>
<Frame.HeightRequest>
<MultiBinding Converter="{StaticResource SizeConverter}" >
<MultiBinding.Bindings>
<Binding Path="ActualHeight" />
<Binding Path="Padding" />
<Binding Path="BindingContext.Board.Rows" />
</MultiBinding.Bindings>
</MultiBinding>
</Frame.HeightRequest>
</Frame >
中获取值了。
但是Converter
似乎不是现有的可绑定属性。