有没有一种方法可以在 Xamarin.Forms Button 中设置多行文本?
我已经尝试过 Button.Text = "something \n xxjjjxx" ,但不起作用。
有没有一种方法可以在 Xamarin.Forms Button 中设置多行文本?
我已经尝试过 Button.Text = "something \n xxjjjxx" ,但不起作用。
一个简单的解决方案将会使用:


在Github上有一个非常好的例子,展示了如何实现这个功能。实际上很简单,只需要创建自己的控件,继承自ContentView,并包含一个网格。
[ContentProperty("Content")]
public class MultiLineButton : ContentView
{
public event EventHandler Clicked;
protected Grid ContentGrid;
protected ContentView ContentContainer;
protected Label TextContainer;
public String Text
{
get
{
return (String)GetValue(TextProperty);
}
set
{
SetValue(TextProperty, value);
OnPropertyChanged();
RaiseTextChanged();
}
}
public new View Content
{
get { return ContentContainer.Content; }
set
{
if (ContentGrid.Children.Contains(value))
return;
ContentContainer.Content = value;
}
}
public static BindableProperty TextProperty = BindableProperty.Create(
propertyName: "Text",
returnType: typeof(String),
declaringType: typeof(MultiLineButton),
defaultValue: null,
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: TextValueChanged);
private static void TextValueChanged(BindableObject bindable, object oldValue, object newValue)
{
((MultiLineButton)bindable).TextContainer.Text = (String)newValue;
}
public event EventHandler TextChanged;
private void RaiseTextChanged()
{
if (TextChanged != null)
TextChanged(this, EventArgs.Empty);
}
public MultiLineButton()
{
ContentGrid = new Grid
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand
};
ContentGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
ContentGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
ContentContainer = new ContentView
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
TextContainer = new Label
{
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
ContentContainer.Content = TextContainer;
ContentGrid.Children.Add(ContentContainer);
var button = new Button
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.FromHex("#01000000")
};
button.Clicked += (sender, e) => OnClicked();
ContentGrid.Children.Add(button);
base.Content = ContentGrid;
}
public void OnClicked()
{
if (Clicked != null)
Clicked(this, new EventArgs());
}
}
然后可以像这样使用:
<local:MultiLineButton x:Name="AssessmentToolDetailButton"
WidthRequest="100" HeightRequest="60" BackgroundColor="Blue">
<StackLayout HorizontalOptions="Center" VerticalOptions="CenterAndExpand">
<Label Text="Hello" TextColor="White" Font="16"/>
<Label Text="World" TextColor="White" Font="16"/>
</StackLayout>
</local:MultiLineButton>
您还可以通过设置按钮的内容来放置图像。
在我的示例中,我修改了丹的原始代码以使文本可绑定。只需设置Text值而不是Content,如下所示:
<local:MultiLineButton Text="{Binding Description}" />
所有的荣誉归功于Danvanderboom提供的示例: ConentButton by Danvanderboom
这主要是 iOS 的问题,因为 Android 默认会自动换行。我尝试了 Kasper 提供的解决方案,虽然可以解决问题,但按钮没有圆角,外观与应用中的其他按钮不一致。
一个简单的解决方案是使用自定义渲染器(ButtonRenderer)将 LineBreakMode 设置为 WordWrap。如果您在 Xaml 中设置按钮的宽度,则可以使单词出现在不同的行上。
iOS
public class WrappedButtonRenderer: ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
Control.TitleEdgeInsets = new UIEdgeInsets(4, 4, 4, 4);
Control.TitleLabel.LineBreakMode = UILineBreakMode.WordWrap;
Control.TitleLabel.TextAlignment = UITextAlignment.Center;
}
}
Android默认情况下不需要自定义渲染器,因为它具有默认的包装功能。
这是Xamarin Forms中已知的问题。
StackLayout
中,这对我无效。 - testing我认为我很少见到两行按钮。您有两个选择,我认为可能会起作用:
TapGestureRecognizer
与您的视图一起使用,并将其视为按钮。在fireydude的回答的基础上,我创建了一个MultilineButton控件和iOS渲染器,以便我可以添加文本对齐。这使用Xamarin.Forms.TextAlignment枚举。
MultilineButton.cs
using Xamarin.Forms;
namespace APP_NAMESPACE.Controls
{
public class MultilineButton : Button
{
public static readonly BindableProperty HorizontalTextAlignmentProperty = BindableProperty.Create(
propertyName: "HorizontalTextAlignment",
returnType: typeof(TextAlignment),
declaringType: typeof(MultilineButton),
defaultValue: TextAlignment.Start
);
public TextAlignment HorizontalTextAlignment
{
get { return (TextAlignment)GetValue(HorizontalTextAlignmentProperty); }
set { SetValue(HorizontalTextAlignmentProperty, value); }
}
}
}
MultilineButtonRenderer.cs
using APP_NAMESPACE.Controls;
using APP_NAMESPACE.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(MultilineButton), typeof(MultilineButtonRenderer))]
namespace APP_NAMESPACE.iOS.Renderers
{
public class MultilineButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (Control == null) { return; }
UIControlContentHorizontalAlignment horizontalAlignment;
UITextAlignment textAlignment;
// We have to use ButtonRenderer, so cast the Element to MultilineButton to get the HorizontalTextAlignment property
var button = (MultilineButton)Element;
if (button == null) { return; }
switch(button.HorizontalTextAlignment)
{
case TextAlignment.Center:
horizontalAlignment = UIControlContentHorizontalAlignment.Center;
textAlignment = UITextAlignment.Center;
break;
case TextAlignment.End:
horizontalAlignment = UIControlContentHorizontalAlignment.Right;
textAlignment = UITextAlignment.Right;
break;
default:
horizontalAlignment = UIControlContentHorizontalAlignment.Left;
textAlignment = UITextAlignment.Left;
break;
}
Control.HorizontalAlignment = horizontalAlignment;
Control.TitleLabel.LineBreakMode = UILineBreakMode.WordWrap;
Control.TitleLabel.TextAlignment = textAlignment;
}
}
}
<controls:MultilineButton Text="This Button is Centered!" HorizontalTextAlignment="Center" />