简体   繁体   中英

How to bind values between two bindable properties in composite control Xamarin Forms?

I have created a Forms control extends from Frame with a Editor and a box view on left side. And i exposed the Text property for Frame so that i can use in XAML Bindings. If i bind the value for text from xaml it appears in editor. But how to set the user edit text back to Frame Text Property without triggering property changed?

    public class MyEditor : Frame
    {
    public static readonly BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(MyEditor), String.Empty);        
    public string Text
    {
        get { return (string)this.GetValue(TextProperty); }
        set
        {
            this.SetValue(TextProperty, value);

            // this set is not calling when used from XAML Bindings 
            if (this.editor != null)
                this.editor.Text = value;
        }
    }

    private Editor editor;
    private BoxView leftView;
    private StackLayout contentHolder;

    public MyEditor()
    {
        this.HasShadow = false;
        this.Padding = 0;
        this.IsClippedToBounds = true;

        contentHolder = new StackLayout()
        {
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.FillAndExpand,
            Orientation = StackOrientation.Horizontal,
            Spacing = 0
        };
        this.Content = contentHolder;

        editor = new Editor();
        editor.TextChanged += editor_TextChanged;
        editor.HorizontalOptions = LayoutOptions.FillAndExpand;
        editor.VerticalOptions = LayoutOptions.FillAndExpand;

        leftView = new BoxView()
        {
            IsVisible = false,
            WidthRequest = 5,
            BackgroundColor = Color.FromHex("ff9900")
        };

        contentHolder.Children.Add(leftView);
        contentHolder.Children.Add(editor);
    }

    void editor_TextChanged(object sender, TextChangedEventArgs e)
    {
        // how to update user edited text back to (Text)TextProperty without triggering OnPropertyChanged ? 

        //Text = editor.text; 
        // this triggers the Property change again.
    }

    protected override void OnPropertyChanged(string propertyName = null)
    {
        base.OnPropertyChanged(propertyName);

        //update the Text property of MyEditor to actual editor
        if (propertyName == TextProperty.PropertyName)
        {
            editor.Text = Text;
        }
    }
}

Xaml Code:

<CustomControl:MyEditor x:Name="cEditor" Text="{Binding Text}"  WidthRequest="300" HeightRequest="150"/>

In your code you set editor's text in the setter of your bindableproperty and in OnPropertyChanged fucntion and also set frame's text in OnTextChanged event - 3 pieces of code.

Instead all this try binding these two texts with two-way binding, like this:

public MyEditor()
{
...
   editor.SetBinding(Editor.TextPropety, new Binding("Text", BindingMode.TwoWay,source:this));

}

Also in your Xaml code change binding mode to two-way binding to reflect text changes in the binding context. Actually, I think if you change the Xaml it will solve your current problem ("set the user edit text back to Frame Text Property"), but imho binding the two texts is more elegant.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM