我正在为我在整个应用程序中使用的常见容器类型制作自定义 ContentView。自定义视图有两个可绑定属性:要在左上角显示的标题(字符串),以及要在右上角显示的按钮列表(List)。
header 属性(和 Contents 属性)按预期工作,但 button 属性根本不起作用。永远不会触发,并且输出控制台中ButtonsPropertyChanged
没有绑定错误消息。我究竟做错了什么?
主页.xaml:
<controls:SectionContainer Header="Text blah"> <!-- Header works -->
<controls:SectionContainer.Buttons>
<!-- This does NOT work - buttons are not shown -->
<ImageButton Source="{Binding SomeIcon}"></ImageButton>
<ImageButton Source="{Binding AnotherIcon}"></ImageButton>
</controls:SectionContainer.Buttons>
<!-- Actual contents here -- this works, the contents are shown -->
</controls:SectionContainer>
SectionContainer.xaml:
<ContentView.Content>
<Frame Style="{StaticResource SectionFrame}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Label x:Name="HeaderLabel" Grid.Column="0" Grid.Row="0" VerticalTextAlignment="Start" VerticalOptions="Start" Style="{StaticResource Header}"></Label>
<StackLayout x:Name="ButtonsContainer" Grid.Row="0" Grid.Column="1" Orientation="Horizontal" HorizontalOptions="End"></StackLayout>
<StackLayout Grid.Column="0" Grid.Row="1" x:Name="Container" Style="{StaticResource Section}"></StackLayout>
</Grid>
</Frame>
</ContentView.Content>
SectionContainer.xaml.cs:
[XamlCompilation(XamlCompilationOptions.Compile)]
[ContentProperty("Contents")]
public partial class SectionContainer : ContentView
{
public IList<View> Contents => Container.Children;
public string Header
{
get => (string)GetValue(HeaderProperty);
set => SetValue(HeaderProperty, value);
}
public static readonly BindableProperty HeaderProperty = BindableProperty.Create(
nameof(Header),
typeof(string),
typeof(SectionContainer),
"",
propertyChanged: HeaderPropertyChanged);
private static void HeaderPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
{
((SectionContainer) bindable).HeaderLabel.Text = (string) newvalue;
}
public IList<View> Buttons
{
get => (IList<View>)GetValue(ButtonsProperty);
set => SetValue(ButtonsProperty, value);
}
public static readonly BindableProperty ButtonsProperty = BindableProperty.Create(
nameof(Buttons),
typeof(IList<View>),
typeof(SectionContainer),
new List<View>(),
BindingMode.OneWay,
propertyChanged: ButtonsPropertyChanged);
private static void ButtonsPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
{
Debug.WriteLine(newvalue); // This is never printed, and there are no error messages
var children= ((SectionContainer)bindable).ButtonsContainer.Children;
children.Clear();
foreach (var child in (IList<View>) newvalue)
children.Add(child);
}
public SectionContainer()
{
InitializeComponent();
}
}