我正试图为一个类似于Bootstrap的Navigation Pills的控件创建一个自定义ContentView。
下面是我的自定义视图的代码。
PillToggle.xaml.cs
public partial class PillToggle : ContentView
{
public PillToggle()
{
InitializeComponent();
this.BindingContext = this;
// BindableLayout.SetItemsSource(this.PillsContainer, this.Pills);
}
public ObservableCollection<Pill> Pills
{
get { return (ObservableCollection<Pill>)GetValue(PillsProperty); }
set { SetValue(PillsProperty, value); }
}
public static readonly BindableProperty PillsProperty =
BindableProperty.Create("Pills", typeof(ObservableCollection<Pill>), typeof(PillToggle), defaultValue: new ObservableCollection<Pill>());
}
PillToggle.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:REDACTED"
x:Class="REDACTED.PillToggle">
<Frame BackgroundColor="#eeeeee" CornerRadius="24" Padding="4" MinimumHeightRequest="48">
<HorizontalStackLayout x:Name="PillsContainer" BindableLayout.ItemsSource="{Binding Pills}" HorizontalOptions="Start" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="controls:Pill">
... snip
</DataTemplate>
</BindableLayout.ItemTemplate>
</HorizontalStackLayout>
</Frame>
</ContentView>
Pill.cs
public partial class Pill : ObservableObject
{
[ObservableProperty]
public string? label;
[ObservableProperty]
private bool selected = false;
}
当我尝试在ContentPage中使用此视图时,无法通过XAML绑定Pills集合。
MyPageViewModel.cs
public partial class MyViewModel : ObservableObject
{
//Hard coded for now, but may become dynamic
public IEnumerable<Pill> MyPills { get; } = new List<Pill>()
{
new Pill() { Label = "Test 1" },
new Pill() { Label = "Test 2" }
};
}
MyPage.xaml(用法)
<controls:PillToggle x:Name="MyToggle" Pills="{Binding MyPills}" >
MyPage.xaml.cs(构造函数)
public MyPage(MyViewModel viewModel)
{
this.BindingContext = viewModel;
InitializeComponent();
}
当我运行我的应用程序时,我没有看到任何药片。我可以看到Views的背景色,但HorizontalStackView似乎没有绑定到任何项目。
如果我从Xaml中删除Binding,并在构造函数后面的代码中手动绑定,它就可以工作。
MyToggle.Pills = new ObservableCollection<Controls.Pill>(viewModel.MyPills);
如果我像这样手动添加药片也会起作用。
<controls:PillToggle x:Name="MyToggle">
<controls:PillToggle.Pills>
<controls: Pill Label="Test 3" Selected="True" />
<controls: Pill Label="Test 4" />
</controls:PillToggle.Pills>
</controls:PillToggle>
如何让Binding在Xaml中为我的自定义ContentView工作?
2条答案
按热度按时间g6ll5ycj1#
首先,这是我的观点,你应该避免在你的控制中有一个绑定上下文。它会让你的生活变得简单得多。您拥有的bindingcontext从ContentPage(View)继承的视图模型。你也混合了很多东西,使它比它更难。所以让我们看看我们如何才能做到这一点。
首先,我们有ContentView逻辑,代码背后。你的BindableProperty有点错误。它需要有实际的propertyname作为它的第一个参数。同样是第二个参数,返回类型是错误的,很大程度上是因为你在所有这些中混合了ObservableCollection。它只需要一个列表。所以代码如下:
如果我们转到xaml页面,我刚刚更改了绑定并添加了一个TapGestureRecognizer,因为您谈到可以单击它。
我把你的模型也简化了。
如果我们现在看一下实现,您将拥有带有控件的视图
它绑定到ViewModel中的MyPills
qkf9rpyu2#
我修改了两件事你的代码就能在我这边工作了,
1,因为药丸是
typeof(ObservableCollection<Pill>
。在MyViewModel中:请更改
收件人:
2.在PillToggle.xaml.cs
变化
到
希望能帮上忙!