Передача параметров эффекта в качестве свойств среды CLR
Свойства общеязыковой среды выполнения (CLR) можно использовать для определения параметров эффекта, не реагирующих на изменения свойств во время выполнения. В этой статье демонстрируется использование свойств среды CLR для передачи параметров эффекту.
Процесс создания параметров эффектов, которые не реагируют на изменения свойств во время выполнения, состоит из указанных далее этапов.
- Создайте класс
public
, являющийся подклассом классаRoutingEffect
. КлассRoutingEffect
представляет независимый от платформы эффект, являющийся оболочкой для внутреннего эффекта, который обычно специфичен для платформы. - Создайте конструктор, вызывающий конструктор базового класса с передачей объединения имени группы разрешения и уникального идентификатора, который был указан для каждого зависящего от платформы класса эффекта.
- Добавьте в класс свойства для каждого параметра, передаваемого эффекту.
Затем параметры можно передать эффекту, указав значение каждого свойства при создании экземпляра эффекта.
В примере приложения показан эффект ShadowEffect
, который добавляет тень к тексту, отображаемому элементом управления Label
. На следующей схеме показаны обязанности каждого проекта в примере приложения, а также связи между ними:
Элемент управления Label
в HomePage
настраивается с помощью класса LabelShadowEffect
в каждом проекте для конкретной платформы. Параметры передаются каждому эффекту LabelShadowEffect
через свойства в классе ShadowEffect
. Каждый класс LabelShadowEffect
является производным от класса PlatformEffect
для каждой платформы. В результате тень добавляется к тексту, отображаемому элементом управления Label
, как показано на следующих снимках экрана.
Создание параметров эффекта
Необходимо создать класс public
, являющийся подклассом класса RoutingEffect
, для представления параметров эффекта, как показано в следующем примере кода:
public class ShadowEffect : RoutingEffect
{
public float Radius { get; set; }
public Color Color { get; set; }
public float DistanceX { get; set; }
public float DistanceY { get; set; }
public ShadowEffect () : base ("MyCompany.LabelShadowEffect")
{
}
}
Эффект ShadowEffect
содержит четыре свойства, представляющие параметры, которые следует передать каждому классу LabelShadowEffect
для конкретной платформы. Конструктор класса вызывает конструктор базового класса, передавая параметр, состоящий из объединения имени группы разрешения и уникального идентификатора, который был указан для каждого зависящего от платформы класса эффекта. Поэтому при создании экземпляра ShadowEffect
в коллекцию Effects
элемента управления добавляется новый экземпляр MyCompany.LabelShadowEffect
.
Использование эффекта
В следующем примере кода XAML показан элемент управления Label
, к которому присоединяется ShadowEffect
:
<Label Text="Label Shadow Effect" ...>
<Label.Effects>
<local:ShadowEffect Radius="5" DistanceX="5" DistanceY="5">
<local:ShadowEffect.Color>
<OnPlatform x:TypeArguments="Color">
<On Platform="iOS" Value="Black" />
<On Platform="Android" Value="White" />
<On Platform="UWP" Value="Red" />
</OnPlatform>
</local:ShadowEffect.Color>
</local:ShadowEffect>
</Label.Effects>
</Label>
В следующем примере кода показан эквивалентный элемент управления Label
на языке C#.
var label = new Label {
Text = "Label Shadow Effect",
...
};
Color color = Color.Default;
switch (Device.RuntimePlatform)
{
case Device.iOS:
color = Color.Black;
break;
case Device.Android:
color = Color.White;
break;
case Device.UWP:
color = Color.Red;
break;
}
label.Effects.Add (new ShadowEffect {
Radius = 5,
Color = color,
DistanceX = 5,
DistanceY = 5
});
В обоих примерах кода создается экземпляр класса ShadowEffect
. Перед его добавлением в коллекцию Effects
элемента управления задаются значения для каждого его свойства. Обратите внимание на то, что свойство ShadowEffect.Color
использует значения цвета для конкретной платформы. Дополнительные сведения см. в разделе о классе Device.
Создание эффекта на каждой платформе
В следующих разделах рассматривается реализация класса LabelShadowEffect
для каждой платформы.
Проект на платформе iOS
В следующем примере кода показана реализация класса LabelShadowEffect
для проекта на платформе iOS:
[assembly:ResolutionGroupName ("MyCompany")]
[assembly:ExportEffect (typeof(LabelShadowEffect), "LabelShadowEffect")]
namespace EffectsDemo.iOS
{
public class LabelShadowEffect : PlatformEffect
{
protected override void OnAttached ()
{
try {
var effect = (ShadowEffect)Element.Effects.FirstOrDefault (e => e is ShadowEffect);
if (effect != null) {
Control.Layer.ShadowRadius = effect.Radius;
Control.Layer.ShadowColor = effect.Color.ToCGColor ();
Control.Layer.ShadowOffset = new CGSize (effect.DistanceX, effect.DistanceY);
Control.Layer.ShadowOpacity = 1.0f;
}
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
}
}
Метод OnAttached
получает экземпляр ShadowEffect
и задает для свойств Control.Layer
соответствующие значения для создания тени. Ели у элемента управления, к которому присоединен эффект, отсутствуют свойства Control.Layer
, указанная выше функциональность заключается в блок try
/catch
. Поскольку очистка не требуется, метод OnDetached
не предоставляет реализацию.
Проект на платформе Android
В следующем примере кода показана реализация класса LabelShadowEffect
для проекта на платформе Android:
[assembly:ResolutionGroupName ("MyCompany")]
[assembly:ExportEffect (typeof(LabelShadowEffect), "LabelShadowEffect")]
namespace EffectsDemo.Droid
{
public class LabelShadowEffect : PlatformEffect
{
protected override void OnAttached ()
{
try {
var control = Control as Android.Widget.TextView;
var effect = (ShadowEffect)Element.Effects.FirstOrDefault (e => e is ShadowEffect);
if (effect != null) {
float radius = effect.Radius;
float distanceX = effect.DistanceX;
float distanceY = effect.DistanceY;
Android.Graphics.Color color = effect.Color.ToAndroid ();
control.SetShadowLayer (radius, distanceX, distanceY, color);
}
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
}
}
Метод OnAttached
получает экземпляр ShadowEffect
и вызывает метод TextView.SetShadowLayer
для создания тени с использованием указанных значений свойств. Ели у элемента управления, к которому присоединен эффект, отсутствуют свойства Control.Layer
, указанная выше функциональность заключается в блок try
/catch
. Поскольку очистка не требуется, метод OnDetached
не предоставляет реализацию.
Проект на универсальной платформе Windows
В следующем коде показана реализация класса LabelShadowEffect
для проекта на универсальной платформе Windows (UWP):
[assembly: ResolutionGroupName ("Xamarin")]
[assembly: ExportEffect (typeof(LabelShadowEffect), "LabelShadowEffect")]
namespace EffectsDemo.UWP
{
public class LabelShadowEffect : PlatformEffect
{
bool shadowAdded = false;
protected override void OnAttached ()
{
try {
if (!shadowAdded) {
var effect = (ShadowEffect)Element.Effects.FirstOrDefault (e => e is ShadowEffect);
if (effect != null) {
var textBlock = Control as Windows.UI.Xaml.Controls.TextBlock;
var shadowLabel = new Label ();
shadowLabel.Text = textBlock.Text;
shadowLabel.FontAttributes = FontAttributes.Bold;
shadowLabel.HorizontalOptions = LayoutOptions.Center;
shadowLabel.VerticalOptions = LayoutOptions.CenterAndExpand;
shadowLabel.TextColor = effect.Color;
shadowLabel.TranslationX = effect.DistanceX;
shadowLabel.TranslationY = effect.DistanceY;
((Grid)Element.Parent).Children.Insert (0, shadowLabel);
shadowAdded = true;
}
}
} catch (Exception ex) {
Debug.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
}
}
На платформе UWP эффект тени отсутствует, поэтому реализация LabelShadowEffect
на обеих платформах имитирует его, добавляя второй класс смещения Label
за основной экземпляр Label
. Метод OnAttached
получает экземпляр ShadowEffect
, создает элемент управления Label
и задает для Label
определенные свойства макета. Затем он создает тень, задавая свойства TextColor
, TranslationX
и TranslationY
для управления цветом и расположением Label
. shadowLabel
является смещением, вставленным за основной экземпляр Label
. Ели у элемента управления, к которому присоединен эффект, отсутствуют свойства Control.Layer
, указанная выше функциональность заключается в блок try
/catch
. Поскольку очистка не требуется, метод OnDetached
не предоставляет реализацию.
Итоги
В этой статье было продемонстрировано использование свойств среды CLR для передачи параметров эффекту. Свойства среды CLR можно использовать для определения параметров эффекта, не реагирующих на изменения свойств во время выполнения.