【问题标题】:Properties of custom control can only be filled by StaticResource but not with values defined in XAML自定义控件的属性只能由 StaticResource 填充,不能用 XAML 中定义的值填充
【发布时间】:2019-07-29 12:41:07
【问题描述】:

我基于此https://www.clearpeople.com/insights/blog/2019/February/how-to-create-a-contentview-with-expandable-functionality 创建了自己的ExpandableView 但与所有 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 中定义的所有值都不会传递给属性。我在这里做错了什么?

【问题讨论】:

    标签: c# xaml xamarin.forms controls


    【解决方案1】:

    在定义您自己的 BindableProperty 属性时,希望通过 BindableObject.SetValue/BindableObject.GetValue 访问这些值的最终来源。 Xamarin 运行时可以直接使用它,而不是通过您的 get/set 方法。

    以 TitleText 为例,实现应该是这样的:

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

    链接的文章确实做到了这一点。

    为了创建属性和显示的标题之间的链接,在构造函数中建立数据绑定,将标题标签的Text链接到ExpandableView构造函数中的TitleText属性:

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

    【讨论】:

    • 谢谢,现在工作正常。必须为_Content 使用ContentView 而不是View,所以我可以将属性ExpendableContent 绑定到它并将其永久附加到_ContentLayout。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 2015-01-27
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多