如何在Xamarin表单中通过数据绑定指定的位置放置文本



我正在寻找的功能是可点击的标签,其中文本和位置都是绑定的,并且位置相对于也正在显示的图像。

我已经尝试了AbsoluteLayoutRelativeLayout,但标签似乎无法逃脱CollectionView的限制;也就是说,标签会根据标签的大小在页面上不断迭代。我不在乎标签是否重叠。事实上,如果标签的字体足够大,并且绑定位置足够近,那么重叠标签是肯定的,并且从逻辑上讲,点击事件可能发生在该像素位置上的任何标签上。我没意见。

例如,我想显示一张640x480像素的图像。标签的文本和位置,我想放置在他们需要绑定。这是MockData的样品。

public MockDataStore()
{
items = new List<Item>()
{
new Item { Id = Guid.NewGuid().ToString(), Text = "A"  , Description="My A"  , X= 85, Y=130 },
new Item { Id = Guid.NewGuid().ToString(), Text = "B"  , Description="My B"  , X=140, Y=150 },
new Item { Id = Guid.NewGuid().ToString(), Text = "C"  , Description="My C"  , X=190, Y=165 },
new Item { Id = Guid.NewGuid().ToString(), Text = "D"  , Description="My D"  , X=240, Y=175 },
new Item { Id = Guid.NewGuid().ToString(), Text = "E"  , Description="My E"  , X=290, Y=180 },
new Item { Id = Guid.NewGuid().ToString(), Text = "F"  , Description="My F"  , X=335, Y=185 }
};
}

这里是我正在尝试的XAML。

<Grid x:Name="grid" 
x:DataType="local:ItemsViewModel">
<!--<Image Source="bg.png" Aspect="AspectFit" HorizontalOptions="Start" VerticalOptions="Start" x:Name="bg"/>-->
<RefreshView x:DataType="local:ItemsViewModel" 
Command="{Binding LoadItemsCommand}" 
IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
<CollectionView x:Name="ItemsListView"
ItemsSource="{Binding Items}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<RelativeLayout Padding="10" x:DataType="model:Item">
<Label Text="{Binding Text}" 
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=X, Constant={Binding X}}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Y, Constant={Binding Y}}"
BackgroundColor="Transparent" 
FontSize="16" />
<RelativeLayout.GestureRecognizers>
<TapGestureRecognizer 
NumberOfTapsRequired="1"
Command="{Binding Source={RelativeSource AncestorType={x:Type local:ItemsViewModel}}, Path=ItemTapped}"     
CommandParameter="{Binding .}">
</TapGestureRecognizer>
</RelativeLayout.GestureRecognizers>
</RelativeLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
</Grid>

所发生的是标签的相对位置被放置在页面的递增位置。只要我还能得到ItemTapped,我就不会嫁给使用CollectionView

我也尝试过使用BindableLayout没有成功,虽然我不确定我理解如何正确使用该类,而且数据源是所有的文本和位置。

我想要完成的是类似于GPS应用程序如何显示地图并覆盖从数据中加载的可点击的兴趣点,并相对于地图中的坐标。

我想要完成的是什么,甚至可能使用Xamarin的XAML?

编辑:我发现RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0, Constant=0}" TranslationX="{Binding X}"将把标签放在正确的X位置。然而,这个想法不适用于Y位置。CollectionView在页面中保持Y位置递增。我希望CollectionView可以设置为不做任何控件的定位,只允许我通过绑定来设置标签的x/y位置。

将标签放置在正确的X位置。但是,这个想法不适用于Y位置。

问题是你在每个中显示标签CollectionView项,但是它们有不同的RelativeLayout父元素。它有足够的宽度来设置Y值,但不能设置X值。

对于这个场景,我们建议您使用BindableLayout

组合条目。例如

<ContentPage.BindingContext>
<local:ItemsViewModel />
</ContentPage.BindingContext>
<RelativeLayout BindableLayout.ItemsSource="{Binding items}">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="local:Item">
<Label
BackgroundColor="Transparent"
FontSize="16"
RelativeLayout.XConstraint="{Binding X}"
RelativeLayout.YConstraint="{Binding Y}"
Text="{Binding Text}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</RelativeLayout>

代码后面

public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
public class ItemsViewModel
{
public ItemsViewModel()
{
MockDataStore();
}
public List<Item> items { get; set; }
public void MockDataStore()
{
items = new List<Item>()
{
new Item { Id = Guid.NewGuid().ToString(), Text = "A"  , Description="My A"  ,X = Constraint.Constant(85),Y= Constraint.Constant(130)},
new Item { Id = Guid.NewGuid().ToString(), Text = "B"  , Description="My B"  ,X = Constraint.Constant(140),Y= Constraint.Constant(150)},
new Item { Id = Guid.NewGuid().ToString(), Text = "C"  , Description="My C"  ,X = Constraint.Constant(190),Y= Constraint.Constant(165)},
new Item { Id = Guid.NewGuid().ToString(), Text = "D"  , Description="My D"  ,X = Constraint.Constant(240),Y= Constraint.Constant(175)},
new Item { Id = Guid.NewGuid().ToString(), Text = "E"  , Description="My E"  ,X = Constraint.Constant(290),Y= Constraint.Constant(180)},
new Item { Id = Guid.NewGuid().ToString(), Text = "F"  , Description="My F"  ,X = Constraint.Constant(335),Y= Constraint.Constant(185)}
};
}
}
public class Item
{
public string Id { get; internal set; }
public string Text { get; internal set; }
public string Description { get; internal set; }
public Constraint X { get; set; }
public Constraint Y { get; set; }
}

相关内容

  • 没有找到相关文章

最新更新