Свойства пользовательского элемента управления могут быть заполнены только StaticResource, но не значениями, определенными в XAML - PullRequest
1 голос
/ 07 марта 2019

Я создал свой собственный ExpandableView на основе этого https://www.clearpeople.com/insights/blog/2019/February/how-to-create-a-contentview-with-expandable-functionality, но, как и весь код C #.

Мой элемент управления выглядит так (без анимации)

public class ExpandableView : ContentView
{
    public static readonly BindableProperty ExpandableContentProperty = BindableProperty.Create(nameof(ExpandableContent), typeof(View), typeof(ExpandableView));
    public static readonly BindableProperty TitleTextProperty = BindableProperty.Create(nameof(TitleText), typeof(string), typeof(ExpandableView));


    public View ExpandableContent
    {
        get => this._content;
        set
        {
            if (this._content == value)
            {
                return;
            }
            OnPropertyChanging();
            if (this._content != null)
            {
                this._ContentLayout.Children.Remove(this._content);
            }
            this._content = value;
            this._ContentLayout.Children.Add(this._content);

            OnPropertyChanged();
        }
    }

    public string TitleText
    {
        get => this._Title.Text;
        set
        {
            if (this._Title.Text == value)
            {
                return;
            }
            OnPropertyChanging();
            this._Title.Text = value;
            OnPropertyChanged();
        }
    }

    private readonly StackLayout _OuterLayout;
    private readonly StackLayout _ContentLayout;
    private readonly StackLayout _TitleLayout;
    private View _content;
    private readonly Label _Title;

    public ExpandableView()
    {
        this._OuterLayout = new StackLayout();

        this._ContentLayout = new StackLayout();
        this._TitleLayout = new StackLayout
        {
            Orientation = StackOrientation.Horizontal,
        };

        this._Title = new Label
        {
            HorizontalOptions = new LayoutOptions(LayoutAlignment.Start, true),
            HorizontalTextAlignment = TextAlignment.Center,
            VerticalTextAlignment = TextAlignment.Center,
            Text = "Title",
        };
        this._Title.FontSize = Device.GetNamedSize(NamedSize.Medium, this._Title);

        this._TitleLayout.Children.Add(this._Title);

        this._OuterLayout.Children.Add(this._TitleLayout);
        this._OuterLayout.Children.Add(this._ContentLayout);

        Content = this._OuterLayout;
    }
}

Но теперь, когда я пытаюсь использовать его в XAML, как обычно:

<controls:ExpandableView TitleText="Equipment">
    <controls:ExpandableView.ExpandableContent>
        <StackLayout>
            <Label Text="EQ_12345" />
            <Button Command="{Binding ShowDatacommand}" />
        </StackLayout>
    </controls:ExpandableView.ExpandableContent>
</controls:ExpandableView>

Установка свойств для некоторых значений приводит к тому, что заголовок по-прежнему показывает мне «Заголовок», а содержимое не отображается.Если я вместо этого помещу все в StaticResource Все работает просто отлично:

<controls:ExpandableView ExpandableContent="{StaticResource ExpendableViewContent}"
                         TitleText="{StaticResource EquiString}" />

Во время тестирования я установил некоторые точки останова в свойствах, и только когда я использовал {StaticResource}, свойства были установлены.Все значения, определенные непосредственно в XAML, никогда не передавались в свойства.Что я здесь не так делаю?

1 Ответ

1 голос
/ 07 марта 2019

При определении ваших собственных свойств BindableProperty, как ожидается, к определенному источнику значений будут обращаться через BindableObject.SetValue / BindableObject.GetValue. Среда выполнения Xamarin может использовать это непосредственно, а не через ваши методы get / set.

Используя TitleText в качестве примера, реализация должна выглядеть примерно так:

public string TitleText
{
    get => (string)GetValue(TitleTextProperty);
    set
    {
        SetValue(TitleTextProperty, value);
    }
}

Связанная статья делает это.

Чтобы создать связь между свойством и отображаемым заголовком, установите привязку данных в конструкторе, чтобы связать текст метки заголовка со свойством TitleText в конструкторе ExpandableView:

_Title.SetBinding(Label.TextProperty, new Binding(nameof(TitleText)) { Source = this });
...