我正在尝试创建一个自定义控件,该控件内部具有ListView并填充在父控件中。这是代码:
用于测试的模型(TestModel.cs):
public class TestModel
{
public string TestText { get; set; }
public TestModel(string text)
{
TestText = text;
}
}
自定义控件代码(TestControl.xaml.cs):
public partial class TestControl : ContentView
{
public static readonly BindableProperty TestItemsProperty =
BindableProperty.Create(nameof(TestItems), typeof(ObservableCollection<TestModel>), typeof(TestControl), default);
public ObservableCollection<TestModel> TestItems
{
get => (ObservableCollection<TestModel>)GetValue(TestItemsProperty);
set => SetValue(TestItemsProperty, value);
}
public TestControl()
{
InitializeComponent();
BindingContext = this;
}
}
自定义控件XAML(TestControl.xaml):
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="SalesNet.Mobile.Controls.TestControl">
<StackLayout>
<ListView ItemsSource="{Binding TestItems}"
x:Name="lv">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding TestText}"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentView>
包含控件(TestViewModel.cs)的页面的视图模型:
public class TestViewModel : BaseViewModel
{
private ObservableCollection<TestModel> testModels;
public ObservableCollection<TestModel> TestModels
{
get { return testModels; }
set { SetProperty(ref testModels, value); }
}
public Command LoadTestModels { get; set; }
public TestViewModel()
{
var models = new List<TestModel>()
{
new TestModel("a"),
new TestModel("b")
};
TestModels = new ObservableCollection<TestModel>(models);
LoadTestModels = new Command(async () => await ExecuteLoadTestModels());
}
private async Task ExecuteLoadTestModels()
{
IsBusy = true;
await Task.Delay(2000);
var models = new List<TestModel>()
{
new TestModel("a"),
new TestModel("b"),
new TestModel("c")
};
// I have tried this
TestModels.Clear();
foreach (var model in models)
TestModels.Add(model);
// And this
TestModels = new ObservableCollection<TestModel>(models);
IsBusy = false;
}
}
包含控件的页面,代码(TestPage.xaml.cs):
public partial class TestPage : ContentPage
{
private TestViewModel viewModel;
public TestPage()
{
InitializeComponent();
BindingContext = viewModel = new TestViewModel();
}
protected override void OnAppearing()
{
base.OnAppearing();
viewModel.LoadTestModels.Execute(null);
}
}
包含控件XAML(TestPage.xaml)的页面:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:SalesNet.Mobile.Controls"
mc:Ignorable="d"
x:Class="SalesNet.Mobile.Views.TestPage">
<ContentPage.Content>
<controls:TestControl TestItems="{Binding TestModels}"/>
</ContentPage.Content>
</ContentPage>
我遇到的问题是该集合没有从父项传播到自定义控件。我尝试过重新声明和重新填充集合。这仅在集合中发生。我还尝试过在自定义控件(TestControl.xaml.cs)中编写OnPropertyChanged事件,但没有触发。
答案 0 :(得分:1)
在自定义控件中添加以下方法
public static readonly BindableProperty TestItemsProperty =
BindableProperty.Create(
propertyName: "TestItems",
returnType: typeof(ObservableCollection<TestModel>),
declaringType: typeof(TestControl ),
propertyChanged: OnEventNameChanged);
static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
{
Console.WriteLine(newValue.ToString());
var control = (View1)bindable;
control.lv.ItemsSource = newValue as ObservableCollection<TestModel>;
}
并从构造函数中删除该行
BindingContext = this;