Xamarin Forms: Как да зададете ширината на две колони в мрежа динамично с помощта на mvvm

Трябва да направя изчисление в моя модел на изглед, за да покажа процентен диапазон между две колони в мрежа.

Опитвам се да задам свойство на низ, за ​​да задам стойностите в модела на изгледа, както е показано по-долу,

// These two below values/ratio would be calculated dynamically,

public string firstColValue = "3*";
public string secondColValue = "7*";

<Frame CornerRadius="8" Grid.Row="0" HorizontalOptions="FillAndExpand" HeightRequest="8">
<Grid HorizontalOptions="FillAndExpand">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="{Binding firstColValue}">
            </ColumnDefinition>
            <ColumnDefinition Width="{Binding secondColValue}">
            </ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="8">
            </RowDefinition>
        </Grid.RowDefinitions>

            <Label Grid.Row="0" Grid.Column="0" HeightRequest="8" HorizontalOptions="FillAndExpand" BackgroundColor="Lime"></Label>
            <Label Grid.Row="0" Grid.Column="1" HeightRequest="8" HorizontalOptions="FillAndExpand" BackgroundColor="Blue"></Label>

    </Grid>
</Frame>

Това ми хвърля изключение по време на изпълнение. Опитвам се да задам ширината на двете колони динамично от свойството на модела на изгледа.

Моля, кажете ми как да постигна това.


person Aryan M    schedule 16.01.2019    source източник


Отговори (2)


Тази грешка е, защото обвързвате низ към Width, който изисква друг обект.

За да поправите това, едно от решенията ще бъде използването на Converter, което ще преобразува вашия тип (този, който идва от ViewModel) в очаквания тип за Grid Width. Повече информация за конверторите тук

Конверторът, от който се нуждаете, ще изглежда така:

public class IntToGridLengthConverter : IValueConverter
{
    public IntToGridLengthConverter()
    {
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var intValue = System.Convert.ToInt32(value);
        return new GridLength(intValue, GridUnitType.Star);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Тогава в XAML просто трябва да го използвате.

Добавяне на нов раздел към XAML и извикване на конвертора

<ContentPage.Resources>
    <ResourceDictionary>
        <local:IntToGridLengthConverter x:Key="gridLengthConverter" />
    </ResourceDictionary>
</ContentPage.Resources>

След това използвайте конвертора във вашите обвързвания

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="{Binding firstColValue, Converter={StaticResource gridLengthConverter}}" />            
    <ColumnDefinition Width="{Binding secondColValue, Converter={StaticResource gridLengthConverter}}"/>            
</Grid.ColumnDefinitions>

Както можете да видите, аз използвам Ключа, който беше зададен в предишната част.

Една малка промяна, която трябва да направите във вашите свойства на ViewModel е, че сега те трябва да са от тип int (цяло число). Така че във вашия ViewModel бихте задали само цялата част от стойността, която искате да зададете, например:

firstColValue = 7; 
secondColValue = 3;

Работата по преобразуването на тези стойности съответно в 7* и 3* ще бъде поета от Конвертора.

Използването на конвертори ще ви попречи да използвате елементи Xamarin.Forms във вашите ViewModels, тъй като те трябва да са независими. Освен това този конвертор може да се използва повторно във всяка друга страница, от която се нуждаете.

Надявам се това да помогне.-

person pinedax    schedule 16.01.2019
comment
Благодаря ви за отговора. - person Aryan M; 17.01.2019

Вашият проблем е обектът, който се опитвате да обвържете. Трябва да използвате GridLength

Например

GridLength test =  new GridLength(3, GridUnitType.Star); // which is "3*"

Просто актуализирайте своя ViewModel, за да върнете стойност от тип GridLength

person Bruno Caceiro    schedule 16.01.2019