【发布时间】:2020-12-08 02:31:20
【问题描述】:
我正在构建一个由同类按钮组成的矩形网格,其中包含要在运行时设置的动态行和列。代码在 Xamarin 中。所有最新版本等。 整个项目可以在这里下载:https://github.com/BicycleMark/XamSweeper 我遇到的问题是 XAML 的 MultiBinding 部分。任何评论或建议都会非常棒
我使用 Nested StackPanels 来创建这样的网格:
我成功地创建了一个 MultiValueConverter,用于 调整 正确显示的按钮。我已经用单元测试测试了转换器,它按预期运行。 [R,C] 打印在每个按钮的测试中。这些是从正确绑定的模型中提取的
我遇到的问题是将 MultiBinding 链接到我需要计算按钮大小的 3 个项目:
每个Button的宽度就是用这三个参数计算出来的
- 按住按钮的框架的实际宽度
- 模型按钮的列数
- 每个按钮之间的间距或填充
- 如果任何 [1..3] 为空 返回 50
每个Button的高度就是用这三个参数计算出来的
- 按住按钮的框架的实际高度
- 模型按钮的行数
- 每个按钮之间的间距或填充
- 如果任何 [1..3] 为空 返回 50
这里是转换器描述:
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, object parameter, 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 个空值。这是我要修复的绑定错误
整个项目可以在这里下载:https://github.com/BicycleMark/XamSweeper
【问题讨论】:
标签: c# xamarin mvvm multibinding