如何在复合控件Xamarin Forms中绑定两个可绑定属性之间的值?

时间:2015-11-25 09:10:20

标签: c# xaml xamarin xamarin.forms

我创建了一个Forms控件,使用编辑器和左侧的框视图从Frame扩展。我暴露了Frame的Text属性,以便我可以在XAML Bindings中使用。如果我从xaml绑定文本的值,它将出现在编辑器中。但是如何将用户编辑文本设置回Frame Text Property而不触发属性更改?

    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代码:

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

1 个答案:

答案 0 :(得分:1)

在您的代码中,您可以在bindableproperty的setter和OnPropertyChanged函数中设置编辑器的文本,并在OnTextChanged事件中设置框架文本 - 3段代码。

相反,所有这一切尝试用双向绑定绑定这两个文本,如下所示:

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

}

此外,在您的Xaml代码中,将绑定模式更改为双向绑定,以反映绑定上下文中的文本更改。实际上,我认为如果你改变Xaml它将解决你当前的问题(&#34;将用户编辑文本设置回Frame Text Property&#34;),但imho绑定两个文本更优雅。