Если вы используете функцию , замените на Regex и функцию преобразования в качестве параметров, вы можете создать действительно краткую полностью автономную функцию расширения:
fun String.translateBack() = with(Regex("([bcdfghjklmnpqrstvwxz])o\\1", RegexOption.IGNORE_CASE)) {
replace(this) { "${it.value.first()}" }
}
Пояснение :
Regex будет сопоставлять все одинаковые согласные (независимо от случая) вокруг «o». Чтобы убедиться, что согласные до и после "o" одинаковы, использовалась обратная ссылка к первой группе.
Таким образом, это также будет работать для таких случаев, как «coCatot».
Использование:
println("bob".translateBack()) // b
println("cocatot".translateBack()) // cat
println("coCatot".translateBack()) // cat
На основе этот ответ я сделал простое решение со всего одним классом необходимым и нет никакой потребности реализовать что-то еще в Ваших поведениях.
public static class BehaviorInStyleAttacher
{
#region Attached Properties
public static readonly DependencyProperty BehaviorsProperty =
DependencyProperty.RegisterAttached(
"Behaviors",
typeof(IEnumerable),
typeof(BehaviorInStyleAttacher),
new UIPropertyMetadata(null, OnBehaviorsChanged));
#endregion
#region Getter and Setter of Attached Properties
public static IEnumerable GetBehaviors(DependencyObject dependencyObject)
{
return (IEnumerable)dependencyObject.GetValue(BehaviorsProperty);
}
public static void SetBehaviors(
DependencyObject dependencyObject, IEnumerable value)
{
dependencyObject.SetValue(BehaviorsProperty, value);
}
#endregion
#region on property changed methods
private static void OnBehaviorsChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is IEnumerable == false)
return;
var newBehaviorCollection = e.NewValue as IEnumerable;
BehaviorCollection behaviorCollection = Interaction.GetBehaviors(depObj);
behaviorCollection.Clear();
foreach (Behavior behavior in newBehaviorCollection)
{
// you need to make a copy of behavior in order to attach it to several controls
var copy = behavior.Clone() as Behavior;
behaviorCollection.Add(copy);
}
}
#endregion
}
и демонстрационное использование
<Style TargetType="telerik:RadComboBox" x:Key="MultiPeriodSelectableRadComboBox">
<Setter Property="AllowMultipleSelection" Value="True" />
<Setter Property="behaviors:BehaviorInStyleAttacher.Behaviors">
<Setter.Value>
<collections:ArrayList>
<behaviors:MultiSelectRadComboBoxBehavior
SelectedItems="{Binding SelectedPeriods}"
DelayUpdateUntilDropDownClosed="True"
SortSelection="True"
ReverseSort="True" />
</collections:ArrayList>
</Setter.Value>
</Setter>
</Style>
, не забывают добавлять этот xmlns для использования ArrayList:
xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
Поведенческий код ожидает визуал, поэтому мы можем добавить его только на визуал. Поэтому единственный вариант, который я вижу, это добавить в один из элементов внутри ControlTemplate, чтобы поведение добавлялось в стиль и влияло на все экземпляры конкретного элемента управления.