2

目前我正在玩.Net Maui,但我可能与 Xamarin 的行为相同。

我创建了一个简单的 Search-Control,它基于ContentView.

ObjectSearchControl.xaml

    <ContentView
        x:Class="DeepBlue.Controls.ObjectSearchControl"
        xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:converter="clr-namespace:DeepBlue.Converter"
        xmlns:selector="clr-namespace:DeepBlue.Helpers"
    x:Name="MySearchControl">
    <StackLayout
            Orientation="Vertical"
            VerticalOptions="FillAndExpand">
        <SearchBar
                x:Name="ObjectSearchBar"
                IsSpellCheckEnabled="False"
                Keyboard="Text"
                Placeholder="{Binding SearchBarPlaceholderText}"
                TextChanged="ObjectSearchBar_TextChanged" />

        <CollectionView
                x:Name="ObjectResultView"
                HeightRequest="500"
                ItemsSource="{Binding DataSource}"
                SelectionChanged="ObjectResultView_SelectionChanged">
        </CollectionView>
    </StackLayout>
</ContentView>

ObjectSearchControl.xaml.cs

    public partial class ObjectSearchControl : ContentView
    {
        public static readonly BindableProperty SearchBarPlaceholderTextProperty
        = BindableProperty.Create(nameof(SearchBarPlaceholderText), typeof(string),
            typeof(ObjectSearchControl), string.Empty);

    public static readonly BindableProperty DataSourceProperty
        = BindableProperty.Create(nameof(DataSource), typeof(object),
            typeof(ObjectSearchControl));


    public ObjectSearchControl()
    {
        InitializeComponent();

        Content.BindingContext = this;
    }

    public string SearchBarPlaceholderText
    {
        get => (string)GetValue(SearchBarPlaceholderTextProperty);
        set => SetValue(SearchBarPlaceholderTextProperty, value);
    }


        public object DataSource
        {
            get => (object)GetValue(DataSourceProperty);
            set => SetValue(DataSourceProperty, value);
        }
    }

ContentView是我在我的页面中插入的

            <StackLayout
                x:Name="SelectFishingSection"
                HeightRequest="600"
                HorizontalOptions="FillAndExpand"
                Orientation="Vertical"
                VerticalOptions="FillAndExpand">

                <controls:ObjectSearchControl
                    DataSource="{Binding NonFilterdDataSource}"
                    HeightRequest="550"
                    HorizontalOptions="FillAndExpand"
                    SearchBarPlaceholderText="Placeholder"
                    VerticalOptions="FillAndExpand" />
            </StackLayout>

运行代码后,控件呈现并且 PlaceholdertextSearchBar设置正确。所以我认为绑定的实现是正确的。但在我CollectionView没有呈现任何元素。

所以我调试了很多,发现BindingContext设置了2次。当我初始化控件时,所有属性都有 NULL 值。-> 看起来不错

然后控件出现,我从 DB 中获取元素并将它们设置为“DataSource”。

    <ContentPage.Behaviors>
        <mctBehaviors:EventToCommandBehavior Command="{Binding SetDataSourcesCommand}" EventName="Appearing" />
    </ContentPage.Behaviors>
    private async Task SetDataSources()
    {
        try
        {
            IsBusy = true;

            NonFilterdDataSource = new ObservableCollection<MyTestModel>(await DataService.GetAll());
        }
        finally
        {
            IsBusy = false;
        }
    }

这也被称为并且似乎是正确的。之后BindingContext设置(OnBindingContextChanged在我的 ObjectSearchControl.xaml.cs 中调用)并且所有属性(SearchBarPlaceholderText 和 DataSource)都有正确的值。此时 DataSource 中有 9 个元素!

如果我继续调试 DataSource 设置为 NULL 并且BindingContext设置为 NULL!但我不明白为什么?VS 中的输出窗口仅显示“外部代码”,我无法弄清楚为什么会发生这种情况。

我发现了一些类似的问题,但没有一个可以解决我的问题。

4

1 回答 1

1

在分析了 VS 中的“外部代码”后,我发现问题的根源一定在控件的测量中。所以我 VerticalOptions="FillAndExpand"从我的controls:ObjectSearchControl实现中删除了,之后问题就消失了。BindingContext 只设置了一次,一切都按预期工作!

于 2022-01-17T18:53:43.720 回答