実行時に設定される動的な行と列を持つ同種のボタンの長方形グリッドを構築しています。コードはXamarinにあります。すべての最新バージョンなど。プロジェクト全体はここからダウンロードできます:https://github.com/BicycleMark/XamSweeper私が抱えている問題は、XAMLのマルチバインディング部分です。レビューや提案は非常に優れています
Nested StackPanelsを使用して、次のようなグリッドを作成しました。
正しく表示されているボタンのサイズを変更するためのMultiValueConverterを作成することに成功しました。ユニットテストでコンバーターをテストしましたが、期待どおりに機能します。[R、C]は各ボタンのテストで印刷されます。これらは正しくバインドされているモデルから取得されます
私が抱えている問題は、ボタンのサイズを計算する必要がある3つのアイテムにマルチバインディングをリンクすることです。
各ボタンの幅は、これら3つのパラメーターを使用して計算されます
各ボタンの高さは、これら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, 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つのnullを渡しています。これは私が修復しようとしているバインディングエラーです
プロジェクト全体はここからダウンロードできます:https://github.com/BicycleMark/XamSweeper
コンバーターが呼び出されていますが、毎回3つのnullを渡しています。
次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
。
しかしActualWidth
、既存のバインド可能なプロパティではないようです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加