【问题标题】:Binding a Custom View In Xamarin.Forms在 Xamarin.Forms 中绑定自定义视图
【发布时间】:2015-12-12 22:00:24
【问题描述】:

我在将 Xamarin 表单中的自定义视图中的数据绑定到包含页面的视图模型时遇到问题。

我的自定义视图很简单,一对标签代表一个键值对:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="KeyValueView">
    <Grid VerticalOptions="Start">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Label x:Name="KeyLabel" Text="{Binding Key}"  Grid.Column="0" HorizontalOptions="Start" />
        <Label x:Name="ValueLabel" Text="{Binding Value}" Grid.Column="1" HorizontalOptions="EndAndExpand" />
    </Grid>
</ContentView>

后面有代码:

public partial class KeyValueView : ContentView
{
    public KeyValueView()
    {
        InitializeComponent();
        this.VerticalOptions = LayoutOptions.Start;
        this.BindingContext = this;
    }

    public static readonly BindableProperty ValueProperty =
                BindableProperty.Create<KeyValueView, string>(w => w.Value, default(string));

    public string Value
    {
        get {return (string)GetValue(ValueProperty);}
        set {SetValue(ValueProperty, value);}
    }

    public static readonly BindableProperty KeyProperty =
        BindableProperty.Create<KeyValueView, string>(w => w.Key, default(string));

    public string Key
    {
        get {return (string)GetValue(KeyProperty);}
        set {SetValue(KeyProperty, value);}
    }
}

在页面中使用如下:

<views:KeyValueView Key="Order Number" Value="{Binding document_number}" />

问题是 Key 字符串按预期显示,但 value 字符串没有。 我尝试在 document_number 属性上强制执行 PropertyChanged 事件,但这没有帮助。 我还尝试在自定义视图的键/值属性的设置器中显式设置标签上的文本属性:

public string Key
    {
        get {return (string)GetValue(KeyProperty);}
        set {
            SetValue(KeyProperty, value);
            KeyLabel.Text = value;
        }
    }

这同样没有帮助,setter 代码似乎永远不会被执行(我在它上面放置了一个断点,它没有被命中)

如果我添加一个开箱即用的控件,例如直接绑定到页面中的属性的标签,则显示正确:

<Label Text="{Binding document_number}"/>
<views:KeyValueView Key="Order Number" Value="{Binding document_number}" />

谁能解释为什么会发生(或者说没有发生)?

【问题讨论】:

    标签: c# xaml xamarin xamarin.forms


    【解决方案1】:

    不要在自定义控件内部分配绑定。使用这个:

    public partial class KeyValueView : ContentView
    {
        public KeyValueView()
        {
            InitializeComponent();
            this.VerticalOptions = LayoutOptions.Start;
        }
    
        public static readonly BindableProperty ValueProperty =
            BindableProperty.Create<KeyValueView, string>(w => w.Value, default(string));
    
        public string Value
        {
            get {return (string)GetValue(ValueProperty);}
            set {SetValue(ValueProperty, value);}
        }
    
        public static readonly BindableProperty KeyProperty =
            BindableProperty.Create<KeyValueView, string>(w => w.Key, default(string));
    
        public string Key
        {
            get {return (string)GetValue(KeyProperty);}
            set {SetValue(KeyProperty, value);}
        }
        protected override void OnPropertyChanged(string propertyName)
        {
            base.OnPropertyChanged(propertyName);
    
            if (propertyName == ValueProperty.PropertyName)
            {
                ValueLabel.Text = Value;
            }
            if (propertyName == KeyProperty.PropertyName)
            {
                KeyLabel.Text = Key;
            }
        }
    }
    
    <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="KeyValueView">
        <Grid VerticalOptions="Start">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <Label x:Name="KeyLabel" Grid.Column="0" HorizontalOptions="Start" />
            <Label x:Name="ValueLabel" Grid.Column="1" HorizontalOptions="EndAndExpand" />
        </Grid>
    </ContentView>
    

    将属性(例如 Value)视为对 BindableProperty (ValueProperty) 的引用。如果您在 Value setter 中执行某些操作,则不会通知 BindableProperty,如果您使用 BindableProperty(分配/更改 ValueProperty)执行某些操作,则相反 - 不会调用属性 Value setter。

    如果您想处理 PropertyChanged,您可以覆盖该 (OnPropertyChanged) 或 Actions(作为创建 BindableProperty 时的附加参数)。

    【讨论】:

    • 这正是我所需要的,谢谢。对于具有很多可绑定属性的自定义视图可能会有点麻烦,但是当我到达那一点时,我会考虑重构
    • 很遗憾 propertyChanged: from BindableProperty 是静态的,自定义属性的重点是要重用,使用这种静态方法,您只能使用一个自定义元素,但您的解决方案就像一个魅力
    • 谢谢! 2天后,我找到了这个问题的正确答案
    【解决方案2】:

    我能够通过这样做来让它工作

    public KeyValueView()
    {
        InitializeComponent();
        this.VerticalOptions = LayoutOptions.Start;
        this.Content.BindingContext = this;
    }
    

    然后在 xaml.cs 中为您使用自定义视图的视图执行此操作:

    public ParentView()
    {
        InitializeComponent();
        BindingContext = this;
    }
    

    对于给我带来问题的 Entry 字段,我必须确保将 defaultBindingMode 参数设置为 TwoWay。

    【讨论】:

    • 这是正确答案!
    猜你喜欢
    • 2017-03-11
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2020-02-06
    • 2021-02-09
    • 2021-06-05
    • 1970-01-01
    • 2018-02-17
    相关资源
    最近更新 更多