【问题标题】:Can't create Bindable Property for custom ContentView无法为自定义 ContentView 创建可绑定属性
【发布时间】:2021-01-27 22:12:11
【问题描述】:

我创建了一个带有单个标签的ContentView(我计划稍后添加更多)。

PageHeadingView.xaml

  <ContentView.Content>
        <StackLayout Orientation="Vertical" BackgroundColor="Red">
            <Label x:Name="HeadingLabel"  Text="{Binding HeadingText}" />
        </StackLayout>
  </ContentView.Content>

我在后面的代码中定义了BindableProperty。我还将我的视图的BindingContext 设置为它自己。

PageHeadingView.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PageHeadingView : ContentView
{
    public PageHeadingView()
    {
        InitializeComponent();
        this.BindingContext = this;
    }

    public static readonly BindableProperty HeadingTextProperty = BindableProperty.Create(nameof(HeadingText), typeof(string), typeof(PageHeadingView), default(string));
    public string HeadingText { get => (string)GetValue( HeadingTextProperty); set => SetValue(HeadingTextProperty, value); }
}

然后我将视图添加到我的 ContentPage。我还在 StackLayout 中添加了一个测试标签,以确保我的绑定正常工作。

HomePage.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:views="clr-namespace:MyProject.Views"
             x:Class="MyProject.HomePage">
    <ContentPage.Content>
        <StackLayout Orientation="Vertical">
            <views:PageHeadingView HeadingText="{Binding Name}" />
            <Label Text="{Binding Name}" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

并在代码中设置我的BindingContext。

HomePage.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomePage : ContentPage
{
    public HomePage()
    {
        InitializeComponent();
        //ViewModel contains a string property named: Name;
        this.BindingContext = new ViewModel();
    }
}

当我运行我的代码时,我的 PageHeadingView 不显示任何文本。我可以看到红色背景颜色,所以我知道控件已正确添加到页面。我在 StackLayout 中放置的测试 Label 也可以正常工作,并且可以看到绑定的值。

我需要做什么才能让我的 CustomView 显示可绑定内容?

【问题讨论】:

    标签: xaml xamarin xamarin.forms data-binding xamarin-binding


    【解决方案1】:

    从您的代码中,您在使用 bindableproperty 出价时可能会遇到一些问题,我创建了一个简单的示例,您可以看看:

    PageHeadingView.xaml:

     <ContentView.Content>
        <StackLayout BackgroundColor="Red" Orientation="Vertical">
            <Label x:Name="HeadingLabel" />
        </StackLayout>
    </ContentView.Content>
    

    PageHeadingView.cs,可以通过 HeadingTextPropertyChanged 更新 HeadingText 值,然后显示 HeadingLabel。

     public partial class PageHeadingView : ContentView
    {
    
        public static BindableProperty HeadingTextProperty= BindableProperty.Create(
                                                         propertyName: "HeadingText",
                                                         returnType: typeof(string),
                                                         declaringType: typeof(PageHeadingView),
                                                         defaultValue: "",
                                                         defaultBindingMode: BindingMode.OneWay,
                                                         propertyChanged: HeadingTextPropertyChanged);
        
        public string HeadingText
        {
            get { return base.GetValue(HeadingTextProperty).ToString(); }
            set { base.SetValue(HeadingTextProperty, value); }
        }
        private static void HeadingTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (PageHeadingView)bindable;
            control.HeadingLabel.Text = newValue.ToString();
        }
    
        public PageHeadingView()
        {
            InitializeComponent();
        }
    }
    
    <StackLayout>
            <customcontrol:PageHeadingView HeadingText="{Binding Name}" />
            <Label Text="{Binding Name}" />
        </StackLayout>
    

    【讨论】:

      【解决方案2】:

      您在 PageHeadingView 中绑定了错误的元素。

      选项 1:
      在 PageHeadingView.xaml.cs 中添加“内容”

      this.Content.BindingContext = this;
      

      选项 2:
      删除 PageHeadingView.xaml 中的“内容”

        <!--<ContentView.Content>-->
              <StackLayout Orientation="Vertical" BackgroundColor="Red">
                  <Label x:Name="HeadingLabel"  Text="{Binding HeadingText}" />
              </StackLayout>
        <!--</ContentView.Content>-->
      

      根据之前引用的错误类进行了编辑。

      【讨论】:

      • 选项 #2 似乎对我不起作用。我尝试了从 Page 和 ContentView 中删除 Content 元素的所有组合,但我的文本仍然没有显示。然而,选项 #1 确实有效。所以谢谢你!
      • 经过进一步调查,我注意到选项 #1 仅适用于绑定值。如果我在 ContentPage 中使用常量,则不会显示该值。出于这个原因,我将 Cherry 的答案标记为正确,因为它可以处理所有情况。
      • 糟糕,我提到了“在 PageHeadingView 中绑定错误的元素”,但后来引用了“HomePage”类,抱歉我的粗心。已编辑,应该与使用 PropertyChanged 方法一样工作。
      猜你喜欢
      • 1970-01-01
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多