【问题标题】:How to make a local ContentView bind a Label text如何使本地 ContentView 绑定标签文本
【发布时间】:2020-08-19 23:10:11
【问题描述】:

我用 Expander 制作了一个 ContentView。我想在另一个 Xaml 文件中多次复制此 Xaml 代码。但我希望每个扩展器都有一个不同的绑定。
我链接了这段代码(ContentView 代码):

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:expandable="clr-namespace:Expandable;assembly=ExpandableView"
             x:Class="Hello.ExpandableView">
    <ContentView.Content>
        <expandable:ExpandableView Padding="5">
    <expandable:ExpandableView.PrimaryView>
        <Frame BackgroundColor="White" Padding="5" CornerRadius="10">
            <StackLayout Orientation="Horizontal">
        <Label x:Name="label" FontSize="16" TextColor="Black" FontAttributes="Bold" Padding="5" HorizontalTextAlignment="Start" HorizontalOptions="StartAndExpand"/>
        <Image Source="arrow.png" WidthRequest="25" HeightRequest="25" Margin="5"/>
                </StackLayout>
    </Frame>
    </expandable:ExpandableView.PrimaryView>
    <expandable:ExpandableView.SecondaryViewTemplate>
        <DataTemplate>
            <Frame BackgroundColor="White" Padding="5" CornerRadius="10">
        <Label Text="{Binding Tip1Uitleg}" FontSize="15" TextColor="Black" Padding="5"/>
                </Frame>
        </DataTemplate>
    </expandable:ExpandableView.SecondaryViewTemplate>
</expandable:ExpandableView>
    </ContentView.Content>
</ContentView>
namespace Hello
{
    public partial class ExpandableView : ContentView
    {
        public static BindableProperty LabelProperty =
    BindableProperty.Create(nameof(Label),
                            typeof(string),
                            typeof(ExpandableView),
                            propertyChanged: (b, o, n) => (b as ExpandableView).OnLabelChanged());

        private void OnLabelChanged()
        {
            label.Text = Label; //label is the x:Name of your Label control in ExpandableView.xaml
        }

        public string Label
        {
            get => (string)GetValue(LabelProperty);
            set => SetValue(LabelProperty, value);
        }
    }
}

至此代码: 这有效:

<local:ExpandableView Label="Hello"/>

但我想要这个。这不起作用:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:expandable="clr-namespace:Expandable;assembly=ExpandableView"
             xmlns:local="clr-namespace:Hello"
             x:Class="Hello.Health.HealthDetail"
             Title="{Binding Name}">
     <ContentPage.Content>
     <ScrollView>
        <StackLayout>
            <Image Source="{Binding Image}"/>
            <Label Text="{Binding Tip1Uitleg}" FontSize="15" TextColor="Black" Padding="10, 5, 10, 5"/>

            <local:ExpandableView Label="{Binding Tip1}"/> //This is what it is all about
</StackLayout>
            </ScrollView>
    </ContentPage.Content>
</ContentPage>

代码隐藏:

namespace Hello.Health
{
    public partial class HealthDetail : ContentPage
    {
        public HealthDetail(HealthStrings healthStrings)
        {
            if (healthStrings == null)
                throw new ArgumentNullException();

            BindingContext = healthStrings;

            InitializeComponent();


        }
    }
}

我该如何进行这项工作?我必须使上面的内容更加动态,但我不知道如何。

顺便说一句,这也有效:

<Label Text="{Binding Tip1}" />

很抱歉解释不清楚,希望有人能帮助我。 谢谢你的时间:)

【问题讨论】:

    标签: xamarin xamarin.forms binding label local


    【解决方案1】:

    您不应绑定到“this”,因为您使用的是 BindableProperty。相反,您应该在 BindableProperty 的值更改时更新 Label.Text 属性。

    public static BindableProperty LabelProperty =
        BindableProperty.Create(nameof(Label),
                                typeof(string),
                                typeof(ExpandableView),
                                propertyChanged:(b, o, n) => (b as ExpandableView).OnLabelChanged());
    
    private void OnLabelChanged()
    {
        label.Text = Label; //label is the x:Name of your Label control in ExpandableView.xaml
    }
    
    public string Label
    {
        get => (string)GetValue(LabelProperty);
        set => SetValue(LabelProperty, value);
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="YourProject.ExpandableView">
        <Grid>
            <Label x:Name="label"/>
        </Grid>
    </ContentView>
    

    【讨论】:

    • 我用您在 ExpandableView.xaml.cs 中的代码替换了我的代码,并在 ExpandableView.xaml 中添加了 x:Name="label"。但现在我得到一个 systemNullReferenceException。我可以保持 一样吗?我做错了什么?
    • 我在上面编辑了我的答案,包括一个关于您必须添加到标签的名称的示例。我还建议更改您的 Label 属性名称。应该是 LabelText 或 Text 之类的东西,因为您设置的文本是字符串而不是实际的 Label 控件。即使这可能会导致问题。是的,您应该像 那样使用它。您还删除了BindingContext = this; 行吗?
    • 是的,我删除了 BindingContext = this; systemNullReferenceException 表示“对象引用未设置为对象的实例”。感谢您的耐心和帮助:)
    • 检查异常抛出的位置,因为我猜它与上面的代码无关。你能分享你的 ExpandableView.xaml 和代码隐藏代码吗?
    • 如果我将 ExpandableView.Xaml 更改为一个简单的标签(如您上面的代码中所示),它仍然无法正常工作。它仍然给出相同的 systemNullReferenceException。
    【解决方案2】:

    通常,当您想为 binableproperty 绑定值时,您可以尝试以下代码:

    ExpandableView:我制作了一个具有相同 binable 属性的简单内容视图供您参考。

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="XamarinDemo.Pages.ExpandableView">
       <ContentView.Content>
           <StackLayout>
              <Label Text="Hello"></Label>
              <Label x:Name="label"></Label>
           </StackLayout>
       </ContentView.Content>
    </ContentView>
    

    后面的代码:

    public partial class ExpandableView : ContentView
     {
        public static BindableProperty LabelProperty =
     BindableProperty.Create(nameof(Label),
                            typeof(string),
                            typeof(ExpandableView),
                            propertyChanged: (b, o, n) => (b as 
    ExpandableView).OnLabelChanged());
    
        private void OnLabelChanged()
        {
            label.Text = Label; //label is the x:Name of your Label control in ExpandableView.xaml
        }
    
        public string Label
        {
            get => (string)GetValue(LabelProperty);
            set => SetValue(LabelProperty, value);
        }
        public ExpandableView()
        {
            InitializeComponent();
        }
    
     }
    

    用法:

     <ContentPage.Content>
        <local:ExpandableView Label="{Binding str}"></local:ExpandableView>
    </ContentPage.Content>
    

    代码背后:

    public partial class Page1 : ContentPage
      {
        public string str { get; set; }
        public Page1()
        {
            InitializeComponent();
    
            str = "okay";
    
            this.BindingContext = this;
         }
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多