Xamarin.Формы привязывают высоту сетки к ширине кнопки

#xaml #data-binding #xamarin.forms

#xaml #привязка данных #xamarin.forms

Вопрос:

Я пытаюсь создать следующий элемент пользовательского интерфейса с Xamarin.Forms помощью . Я смог создать это с UWP помощью привязки Height свойства TopGrid к ActualWidth свойству Button1 . Однако это не работает в Xamarin.Формы, потому что нет ActualWidth свойства. Я уже пытался привязать Height TopGrid к WidthRequest , но безуспешно.

введите описание изображения здесь

 <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid x:Name="TopGrid" Grid.Row="0" BindingContext="{x:Reference Name=Button1}"  Height="{Binding Path=WidthRequest}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Button x:Name="Button1" Grid.Column="0" Text="1" />
        <Button x:Name="Button2" Grid.Column="1" Text="2" />
        <Button x:Name="Button3" Grid.Column="2" Text="3" />
        <Button x:Name="Button4" Grid.Column="3" Text="4" />
    </Grid>
</Grid>
  

Есть ли у кого-нибудь опыт Xamarin.Forms и может ли он помочь мне с этой проблемой?

Ответ №1:

Перво-наперво: имена Xaml чувствительны к регистру, поэтому вместо

 BindingContext="{x:Reference Name=button1}"
  

это должно быть

 BindingContext="{x:Reference Name=Button1}"
  

Помимо этого, ваш Xaml был почти в порядке. Давайте посмотрим на

 Height="{Binding Path=WidthRequest}"
  

Вы пытаетесь привязать к высоте представления, но HeightProperty свойство BindableProperty доступно только для чтения, поэтому вы не можете его установить. Если вы посмотрите на API, то для Height свойства также нет общедоступного установщика. Итак, вместо привязки к высоте, вы должны привязаться к HeightRequest .

 HeightRequest="{Binding Path=WidthRequest}"
  

Это способ сказать, что вы хотели бы Grid , чтобы она была такой высоты, и система компоновки сделает все возможное, чтобы сделать вас счастливыми (но это только лучшее усилие).

Я думаю, вы уже поняли это. Кнопка WidthRequest — это запрос, сделанный пользователем, и в этом случае он не задан, и его значение оставлено по умолчанию. Вместо этого вы хотите использовать фактическое свойство кнопки Width в качестве исходного для вашей привязки. Давайте сделаем это:

 HeightRequest="{Binding Width}"
  

и это дает ожидаемый результат:

фактический результат

Вот полный исправленный фрагмент Xaml:

 <Grid>
  <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <Grid x:Name="TopGrid" Grid.Row="0" BindingContext="{x:Reference Name=Button1}"  HeightRequest="{Binding Width}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Button x:Name="Button1" Grid.Column="0" Text="1" BackgroundColor="Pink"/>
    <Button x:Name="Button2" Grid.Column="1" Text="2" BackgroundColor="Pink"/>
    <Button x:Name="Button3" Grid.Column="2" Text="3" BackgroundColor="Pink"/>
    <Button x:Name="Button4" Grid.Column="3" Text="4" BackgroundColor="Pink"/>
  </Grid>
</Grid>
  

Ответ №2:

Если вы не хотите устанавливать BindingContext для всей сетки (и каждого элемента в ней), вы можете просто указать его непосредственно в привязке следующим образом, позволяя всем остальным элементам управления сохранять их исходный BindingContext:

  <Grid x:Name="TopGrid" Grid.Row="0" HeightRequest="{Binding Width, Source={x:Reference Button1}}">