Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 75885

Forcing a RelativeLayout in a DataTemplate to update after constraints change

$
0
0

We are prototyping an idea, so this code is far from production-ready. That said, I'll paste the relevant parts below.
We are using an IValueConverter to convert an integer value into a relative constraint to position a BoxView along the X-axis of an image. When the X value in the ViewModel gets updated, so does our binding (we can tell because our value converter is called) and a new constraint is created. However, the RelativeLayout does not update its layout when a constraint is changed.

Add to this, the relative layout is inside a DataTemplate and you get all kinds of fun. :)

Our question: how do you force a RelativeLayout (that is inside a DataTemplate) to redraw itself so the new constraint is used?

Here's part of our ViewModel:

private int _PosX;
        public int PosX
        {
            get { return _PosX;}
            set
            {
                if (_PosX == value)
                    return;

                _PosX = value;
                OnPropertyChanged(nameof(PosX));
            }
        }

The ContentPage:

<Slider Value="{Binding PosX, Mode=TwoWay}"
            Minimum="0" Maximum="640" x:Name="xAdjustmentSlider" />

    <cv:CarouselView x:Name="ImageCarousel" Grid.Row="2"
                     ItemsSource="{Binding ShotList}">
      <cv:CarouselView.ItemTemplate>
        <DataTemplate>
          <Grid x:Name="TemplateGrid">
            <Grid.RowDefinitions>
              <RowDefinition Height="*" />
              <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <RelativeLayout>
              <Image Grid.Row="0"
                     x:Name="targetImage"
                     Source="{Binding TheImage}"
                     Aspect="AspectFit">
                <Image.GestureRecognizers>
                  <TapGestureRecognizer Command="{Binding Path=BindingContext.PreviewImageCommand, Source={x:Reference ImageViewPage}}"
                                        CommandParameter="{Binding ImageNumber}" />
                </Image.GestureRecognizers>
              </Image>
              <BoxView Color="Red"
                       RelativeLayout.XConstraint="{Binding Source={x:Reference xAdjustmentSlider}, Path=BindingContext.PosX, Converter={StaticResource xConv}, ConverterParameter={x:Reference targetImage}}"
                       WidthRequest="4" HeightRequest="4" />
            </RelativeLayout>
          </Grid>
        </DataTemplate>
      </cv:CarouselView.ItemTemplate>
    </cv:CarouselView>

Here's the int -> relative layout constraint converter:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || !(value is System.Int32) || parameter == null || !(parameter is Xamarin.Forms.View))
                return null;

            int val = (int)value;
            View relativeView = (View)parameter;

            var result = Constraint.RelativeToView(relativeView, (Parent, sibling) =>
            {
                return sibling.X + val;
            });

            return result;
        }

Viewing all articles
Browse latest Browse all 75885

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>