使用 Xamarin Forms 的 UWP 自定义渲染器
UWP Custom renderer with Xamarin Forms
我的自定义渲染器有以下代码。正在使用的元素是标签,我正在尝试设置具有圆角边缘的背景颜色。
[assembly: ExportRenderer(typeof(RoundedLabel), typeof(RoundedLabelCustomRenderer))]
namespace MyNamespace.UWP.CustomRenderers
{
public class RoundedLabelCustomRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var view = (RoundedLabel)e.NewElement;
Children.Clear();
var border = new Border
{
CornerRadius = new CornerRadius(view.RoundedCornerRadius),
Background = new SolidColorBrush(view.RoundedBackgroundColor.ToWindows()),
Child = Control
};
Control.Padding = new Windows.UI.Xaml.Thickness(
view.InsidePadding.Left,
view.InsidePadding.Top,
view.InsidePadding.Right,
view.InsidePadding.Bottom);
Control.Foreground = new SolidColorBrush(view.TextColor.ToWindows());
Children.Add(border);
}
}
}
}
对于按钮之类的东西(UWP 中的复合对象),这很好,如果它在 "pure" XAML 中,类似于
<Border background="gray" cornerradius="12">
<TextBlock />
</Border>
会做这份工作。
我只是想找点乐子和玩游戏,试图将这两个片段协调在一起。
如能指出我做错了什么,将不胜感激。
自定义很难实现您的要求LabelRenderer
。因为没有修改背景颜色和Radius
这样的界面。但是,您可以通过自定义 View
来做到这一点。然后在 UWP 客户端项目中,您可以使用 UserControl
来呈现您想要的控件。
CustomNewLabelControl.cs
public class CustomNewLabelControl : View
{
public static readonly BindableProperty LabelTextProperty = BindableProperty.Create(
propertyName: "LabelText",
eturnType: typeof(string),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(string));
public string LabelText
{
get { return (string)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
public static readonly BindableProperty LabelRadiusProperty = BindableProperty.Create(
propertyName: "LabelRadius",
eturnType: typeof(double),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(double));
public double LabelRadius
{
get { return (double)GetValue(LabelRadiusProperty); }
set { SetValue(LabelRadiusProperty, value); }
}
public static readonly BindableProperty LabelBackgroundProperty = BindableProperty.Create(
propertyName: "LabelBackground",
eturnType: typeof(Color),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(Color));
public Color LabelBackground
{
get { return (Color)GetValue(LabelBackgroundProperty); }
set { SetValue(LabelBackgroundProperty, value); }
}
}
NewLabelControl.xaml.cs
public sealed partial class NewLabelControl : UserControl
{
public NewLabelControl()
{
this.InitializeComponent();
this.DataContext = this;
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(NewLabelControl), new PropertyMetadata(0));
public SolidColorBrush LabelBackground
{
get { return (SolidColorBrush)GetValue(LabelBackgroundProperty); }
set { SetValue(LabelBackgroundProperty, value); }
}
public static readonly DependencyProperty LabelBackgroundProperty =
DependencyProperty.Register("LabelBackground", typeof(SolidColorBrush), typeof(NewLabelControl), new PropertyMetadata(0));
public CornerRadius LabelRadius
{
get { return (CornerRadius)GetValue(LabelRadiusProperty); }
set { SetValue(LabelRadiusProperty, value); }
}
public static readonly DependencyProperty LabelRadiusProperty =
DependencyProperty.Register("LabelRadius", typeof(CornerRadius), typeof(NewLabelControl), new PropertyMetadata(0));
public SolidColorBrush LabelForeground
{
get { return (SolidColorBrush)GetValue(LabelForegroundProperty); }
set { SetValue(LabelForegroundProperty, value); }
}
public static readonly DependencyProperty LabelForegroundProperty =
DependencyProperty.Register("LabelForeground", typeof(SolidColorBrush), typeof(NewLabelControl), new PropertyMetadata(0));
}
NewLabelControl.xaml
<Grid>
<Border CornerRadius="{Binding LabelRadius}" Background="{Binding LabelBackground}">
<TextBlock Text="{Binding Text}" Foreground="{Binding LabelForeground }" />
</Border>
</Grid>
CustomNewLabelRanderer.cs
internal class CustomNewLabelRanderer : ViewRenderer<CustomNewLabelControl, NewLabelControl>
{
protected override void OnElementChanged(ElementChangedEventArgs<CustomNewLabelControl> e)
{
base.OnElementChanged(e);
if (Control == null)
{
SetNativeControl(new NewLabelControl());
}
if (e.OldElement != null)
{
}
if (e.NewElement != null)
{
Control.Text = Element.LabelText;
Control.LabelRadius = new Windows.UI.Xaml.CornerRadius(Element.LabelRadius);
Color color = Element.LabelBackground;
Control.LabelBackground = new Windows.UI.Xaml.Media.SolidColorBrush(
Windows.UI.Color.FromArgb(
(byte)(color.A * 255),
(byte)(color.R * 255),
(byte)(color.G * 255),
(byte)(color.B * 255)));
}
}
}
用法
<local:CustomNewLabelControl LabelText="Welcome to Xamarin Forms!"
LabelBackground="Gray" LabelRadius="5"
VerticalOptions="Center"
HorizontalOptions="Center" />
您可能正在寻找的是 Frame
(实际上在 UWP 上呈现为 Border
)。框架让你设置背景颜色和角半径:
<Frame BackgroundColor="Grey" CornerRadius="12" HasShadow="false" Padding="0">
<Label />
</Frame>
Frame
的阴影和内边距默认设置为 20,因此您必须将其删除才能获得所需的结果。
我的自定义渲染器有以下代码。正在使用的元素是标签,我正在尝试设置具有圆角边缘的背景颜色。
[assembly: ExportRenderer(typeof(RoundedLabel), typeof(RoundedLabelCustomRenderer))]
namespace MyNamespace.UWP.CustomRenderers
{
public class RoundedLabelCustomRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var view = (RoundedLabel)e.NewElement;
Children.Clear();
var border = new Border
{
CornerRadius = new CornerRadius(view.RoundedCornerRadius),
Background = new SolidColorBrush(view.RoundedBackgroundColor.ToWindows()),
Child = Control
};
Control.Padding = new Windows.UI.Xaml.Thickness(
view.InsidePadding.Left,
view.InsidePadding.Top,
view.InsidePadding.Right,
view.InsidePadding.Bottom);
Control.Foreground = new SolidColorBrush(view.TextColor.ToWindows());
Children.Add(border);
}
}
}
}
对于按钮之类的东西(UWP 中的复合对象),这很好,如果它在 "pure" XAML 中,类似于
<Border background="gray" cornerradius="12">
<TextBlock />
</Border>
会做这份工作。
我只是想找点乐子和玩游戏,试图将这两个片段协调在一起。
如能指出我做错了什么,将不胜感激。
自定义很难实现您的要求LabelRenderer
。因为没有修改背景颜色和Radius
这样的界面。但是,您可以通过自定义 View
来做到这一点。然后在 UWP 客户端项目中,您可以使用 UserControl
来呈现您想要的控件。
CustomNewLabelControl.cs
public class CustomNewLabelControl : View
{
public static readonly BindableProperty LabelTextProperty = BindableProperty.Create(
propertyName: "LabelText",
eturnType: typeof(string),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(string));
public string LabelText
{
get { return (string)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
public static readonly BindableProperty LabelRadiusProperty = BindableProperty.Create(
propertyName: "LabelRadius",
eturnType: typeof(double),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(double));
public double LabelRadius
{
get { return (double)GetValue(LabelRadiusProperty); }
set { SetValue(LabelRadiusProperty, value); }
}
public static readonly BindableProperty LabelBackgroundProperty = BindableProperty.Create(
propertyName: "LabelBackground",
eturnType: typeof(Color),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(Color));
public Color LabelBackground
{
get { return (Color)GetValue(LabelBackgroundProperty); }
set { SetValue(LabelBackgroundProperty, value); }
}
}
NewLabelControl.xaml.cs
public sealed partial class NewLabelControl : UserControl
{
public NewLabelControl()
{
this.InitializeComponent();
this.DataContext = this;
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(NewLabelControl), new PropertyMetadata(0));
public SolidColorBrush LabelBackground
{
get { return (SolidColorBrush)GetValue(LabelBackgroundProperty); }
set { SetValue(LabelBackgroundProperty, value); }
}
public static readonly DependencyProperty LabelBackgroundProperty =
DependencyProperty.Register("LabelBackground", typeof(SolidColorBrush), typeof(NewLabelControl), new PropertyMetadata(0));
public CornerRadius LabelRadius
{
get { return (CornerRadius)GetValue(LabelRadiusProperty); }
set { SetValue(LabelRadiusProperty, value); }
}
public static readonly DependencyProperty LabelRadiusProperty =
DependencyProperty.Register("LabelRadius", typeof(CornerRadius), typeof(NewLabelControl), new PropertyMetadata(0));
public SolidColorBrush LabelForeground
{
get { return (SolidColorBrush)GetValue(LabelForegroundProperty); }
set { SetValue(LabelForegroundProperty, value); }
}
public static readonly DependencyProperty LabelForegroundProperty =
DependencyProperty.Register("LabelForeground", typeof(SolidColorBrush), typeof(NewLabelControl), new PropertyMetadata(0));
}
NewLabelControl.xaml
<Grid>
<Border CornerRadius="{Binding LabelRadius}" Background="{Binding LabelBackground}">
<TextBlock Text="{Binding Text}" Foreground="{Binding LabelForeground }" />
</Border>
</Grid>
CustomNewLabelRanderer.cs
internal class CustomNewLabelRanderer : ViewRenderer<CustomNewLabelControl, NewLabelControl>
{
protected override void OnElementChanged(ElementChangedEventArgs<CustomNewLabelControl> e)
{
base.OnElementChanged(e);
if (Control == null)
{
SetNativeControl(new NewLabelControl());
}
if (e.OldElement != null)
{
}
if (e.NewElement != null)
{
Control.Text = Element.LabelText;
Control.LabelRadius = new Windows.UI.Xaml.CornerRadius(Element.LabelRadius);
Color color = Element.LabelBackground;
Control.LabelBackground = new Windows.UI.Xaml.Media.SolidColorBrush(
Windows.UI.Color.FromArgb(
(byte)(color.A * 255),
(byte)(color.R * 255),
(byte)(color.G * 255),
(byte)(color.B * 255)));
}
}
}
用法
<local:CustomNewLabelControl LabelText="Welcome to Xamarin Forms!"
LabelBackground="Gray" LabelRadius="5"
VerticalOptions="Center"
HorizontalOptions="Center" />
您可能正在寻找的是 Frame
(实际上在 UWP 上呈现为 Border
)。框架让你设置背景颜色和角半径:
<Frame BackgroundColor="Grey" CornerRadius="12" HasShadow="false" Padding="0">
<Label />
</Frame>
Frame
的阴影和内边距默认设置为 20,因此您必须将其删除才能获得所需的结果。