我无法找到一种简单的方法来创建Xamarin表单按钮作为顶部带有叠加文本的图像。奇怪的是,Button的Image属性只允许图像旁边的文本。
所以我将在这里分享我的代码实现。它包括一个在点击按钮时隐藏键盘的工具,它支持文本属性,图像大小调整和启用。感谢@F。 Badili,@ Sharada Gururaj和其他人寻求帮助。
答案 0 :(得分:0)
我的实施:
public class ImageButton : Grid
// A clickable visual element overlaying a label on an image, serving as a button
{
public event EventHandler Clicked;
public Image TheImage { get; set; }
public Label TheLabel { get; set; }
public bool HideKeyboard { get; set; }
public string Text
{
get
{
if ( TheLabel == null )
return null;
return TheLabel.Text;
}
set
{
if ( TheLabel == null )
return;
TheLabel.Text = value;
}
}
public Color TextColor
{
set
{
if ( TheLabel != null )
TheLabel.TextColor = value;
}
}
public string FontFamily
{
set
{
if ( TheLabel != null )
TheLabel.FontFamily = value;
}
}
public FontAttributes FontAttributes
{
set
{
if ( TheLabel != null )
TheLabel.FontAttributes = value;
}
}
public double FontSize
{
set
{
if ( TheLabel != null )
TheLabel.FontSize = value;
}
}
public double ImageHeightRequest
{
set
{
if ( TheImage != null )
TheImage.HeightRequest = value;
}
}
public double ImageWidthRequest
{
set
{
if ( TheImage != null )
TheImage.WidthRequest = value;
}
}
public ImageButton ( Image image, Label label, bool hideKeyboard = true )
{
TheImage = image;
TheLabel = label;
HideKeyboard = hideKeyboard;
Text = label.Text;
// Construct the control
ConstructControl ();
}
// Invoke the Clicked event; called when ImageButton is tapped
protected virtual void OnClicked ( EventArgs e )
{
if ( Clicked != null )
Clicked ( this, e );
}
private void ConstructControl ()
// Construct the control using a grid with a single cell
{
// Add action performed upon tap
this.AddTap ( () =>
{
// Hide keyboard
if ( HideKeyboard )
DependencyService.Get<IKeyboard> ().HideKeyboard ();
// Fire the event
OnClicked ( EventArgs.Empty );
});
// Bind opacity of image and label to IsEnabled via a converter
TheLabel.SetBinding ( OpacityProperty, new Binding ( "IsEnabled", converter: new BooleanToOpacityConverter (), source: this ) );
TheImage.SetBinding ( OpacityProperty, new Binding ( "IsEnabled", converter: new BooleanToOpacityConverter (), source: this ) );
// Stack image and label on top of each other in a grid with a single cell
this.RowDefinitions.Add ( new RowDefinition { Height = new GridLength ( 1, GridUnitType.Auto ) } );
this.ColumnDefinitions.Add ( new ColumnDefinition { Width = new GridLength ( 1, GridUnitType.Auto ) } );
this.Children.Add ( TheImage, 0, 0 ); // Add image first, so overlaid label will be visible
this.Children.Add ( TheLabel, 0, 0 );
}
public class BooleanToOpacityConverter : IValueConverter
{
public object Convert ( object value, Type targetType, object parameter, CultureInfo culture )
{
var isEnabled = ( value != null ) && (bool)value;
return isEnabled ? 1 : 0.5;
}
public object ConvertBack ( object value, Type targetType, object parameter, CultureInfo culture )
{
throw new NotImplementedException ();
}
}
}
public static class GridExtensions
{
// Grid extension methods
private static void AddTap ( this Grid grid, Action action )
// Allows Grid to be tappable
// action = method to call when Grid is tapped
// Example:
// Grid grid = new Grid ();
// grid.AddTap ( () => MyMethod () );
{
grid.GestureRecognizers.Add ( new TapGestureRecognizer
{
Command = new Command (action)
});
}
}
public interface IKeyboard
{
void HideKeyboard (); // Hide the keyboard
}
iOS:
[assembly: Xamarin.Forms.Dependency (typeof(Keyboard))]
namespace MyApp.iOS
{
public class Keyboard : MyApp.IKeyboard
{
public Keyboard () {}
public void HideKeyboard ()
// Hides the keyboard
{
UIApplication.SharedApplication.KeyWindow.EndEditing ( true );
}
}
}
Android (not tested yet):
[assembly: Xamarin.Forms.Dependency (typeof (Keyboard))]
namespace MyApp.Droid
{
public class Keyboard : MyApp.IKeyboard
{
public Keyboard () {}
public void HideKeyboard ()
// Hides the keyboard
{
var context = Forms.Context;
var inputMethodManager = context.GetSystemService ( Context.InputMethodService ) as InputMethodManager;
if ( inputMethodManager != null && context is Activity )
{
var activity = context as Activity;
var token = activity.CurrentFocus?.WindowToken;
inputMethodManager.HideSoftInputFromWindow ( token, HideSoftInputFlags.None );
activity.Window.DecorView.ClearFocus ();
}
}
}
}
用法示例:
public static ImageButton StandardImageButton ( string buttonText, EventHandler onClickedEventHandler = null, string imageResourceID = "MyApp.standardbutton.png", string imageSource = null,
Color textColour = default(Color), string fontFamily = null, double fontSize = 15D, FontAttributes fontAttributes = FontAttributes.Bold,
double heightRequest = 44D, double widthRequest = 200D, bool hideKeyboard = true )
// Returns tappable image serving as a button
// buttonText = text overlaid onbutton
// Image is sourced from embedded PCL file (Build Action = Embedded Resource) OR, if imageSourceID is non-null, from local platform file in platform-specific location
{
// Background image
Image image = new Image
{
Aspect = Aspect.Fill, // Stretch to fill
HeightRequest = heightRequest,
WidthRequest = widthRequest,
HorizontalOptions = LayoutOptions.CenterAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand
};
if ( imageResourceID == null )
image.Source = ImageSource.FromFile ( imageSource );
else
image.Source = ImageSource.FromResource ( imageResourceID );
// Foreground label
Color colour;
if ( textColour == default(Color) )
colour = Color.Black;
else
colour = textColour;
Label label = new Label
{
Text = buttonText,
TextColor = colour,
FontFamily = fontFamily,
FontSize = fontSize,
FontAttributes = fontAttributes,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center
};
ImageButton ret = new ImageButton ( image, label, hideKeyboard );
ret.Clicked += onClickedEventHandler;
return ret;
}
答案 1 :(得分:0)
如果在代码或xaml中指定btn1.Image,则可以执行此操作
btn1.ContentLayout = new Button.ButtonContentLayout(Button.ButtonContentLayout.ImagePosition.Bottom, 10);
这会给你一个按钮,底部是图片,顶部是文字