如何在复合控件 Xamarin Forms 中绑定两个可绑定属性之间的值?
How to bind values between two bindable properties in composite control Xamarin Forms?
我创建了一个从 Frame 扩展而来的 Forms 控件,左侧有一个编辑器和一个框视图。我公开了框架的文本 属性,以便我可以在 XAML 绑定中使用。如果我绑定来自 xaml 的文本值,它会出现在编辑器中。但是如何在不触发属性更改的情况下将用户编辑文本设置回Frame Text 属性?
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"/>
在您的代码中,您在绑定属性的 setter 和 OnPropertyChanged 函数中设置了编辑器的文本,还在 OnTextChanged 事件中设置了框架的文本 - 3 段代码。
所有这些都尝试使用双向绑定来绑定这两个文本,如下所示:
public MyEditor()
{
...
editor.SetBinding(Editor.TextPropety, new Binding("Text", BindingMode.TwoWay,source:this));
}
另外,在您的 Xaml 代码中,将绑定模式更改为双向绑定,以反映绑定上下文中的文本更改。实际上,我认为如果您更改 Xaml 它将解决您当前的问题 ("set the user edit text back to Frame Text Property"),但恕我直言,将两个文本绑定起来更优雅。
我创建了一个从 Frame 扩展而来的 Forms 控件,左侧有一个编辑器和一个框视图。我公开了框架的文本 属性,以便我可以在 XAML 绑定中使用。如果我绑定来自 xaml 的文本值,它会出现在编辑器中。但是如何在不触发属性更改的情况下将用户编辑文本设置回Frame Text 属性?
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"/>
在您的代码中,您在绑定属性的 setter 和 OnPropertyChanged 函数中设置了编辑器的文本,还在 OnTextChanged 事件中设置了框架的文本 - 3 段代码。
所有这些都尝试使用双向绑定来绑定这两个文本,如下所示:
public MyEditor()
{
...
editor.SetBinding(Editor.TextPropety, new Binding("Text", BindingMode.TwoWay,source:this));
}
另外,在您的 Xaml 代码中,将绑定模式更改为双向绑定,以反映绑定上下文中的文本更改。实际上,我认为如果您更改 Xaml 它将解决您当前的问题 ("set the user edit text back to Frame Text Property"),但恕我直言,将两个文本绑定起来更优雅。