Кажется, самый простой способ - это сделать это двумя регулярными выражениями.
if (preg_match('/[A-Za-z]/', $myString) && preg_match('/[0-9]/', $myString))
{
echo 'Contains at least one letter and one number';
}
Я полагаю, еще один способ сделать это ниже. Там написано «письмо, а потом в какой-то момент число (или наоборот)». Но вышеприведенный текст легче читать по ИМО.
if (preg_match('/[A-Za-z].*[0-9]|[0-9].*[A-Za-z]/', $myString))
{
echo 'Contains at least one letter and one number';
}
К сожалению, сделать это непросто. В идеале вы должны установить ToolTipService.InitialShowDelay на FrameworkElement и позволить ему распространяться оттуда, но оказывается, что это не работает.
Вместо этого вы можете установить его для каждого типа элемента управления вы хотите установить его, например:
<Style TargetType="RibbonButton">
<Setter Property="ToolTipService.InitialShowDelay" Value="2000"/>
</Style>
<Style TargetType="RibbonToggleButton">
<Setter Property="ToolTipService.InitialShowDelay" Value="2000"/>
</Style>
<Style TargetType="RibbonDropDownButton">
<Setter Property="ToolTipService.InitialShowDelay" Value="2000"/>
</Style>
и т. д.
Хотя это довольно подробный способ сделать это, по крайней мере, вам нужно установить его только для каждого типа элемента управления, а не для каждого элемента управления - и если если вы используете его на ленте, то для начала остается лишь несколько элементов управления.
Чтобы избавить себя от лишних хлопот, если вы когда-нибудь захотите изменить значение, вы можете спроектировать приведенный выше код, используя значение ресурса:
<sys:Int32 x:Key="ToolTipInitialShowDelay">2000</sys:Int32>
<Style TargetType="RibbonButton">
<Setter Property="ToolTipService.InitialShowDelay"
Value="{StaticResource ToolTipInitialShowDelay}"/>
</Style>
<Style TargetType="RibbonToggleButton">
<Setter Property="ToolTipService.InitialShowDelay"
Value="{StaticResource ToolTipInitialShowDelay}"/>
</Style>
<Style TargetType="RibbonDropDownButton">
<Setter Property="ToolTipService.InitialShowDelay"
Value="{StaticResource ToolTipInitialShowDelay}"/>
</Style>
В качестве альтернативы, если вы еще не используете стили на основе BasedOn, вы можете сократить его до:
<Style x:Key="ToolTipDefaults">
<Setter Property="ToolTipService.InitialShowDelay" Value="2000"/>
</Style>
<Style TargetType="RibbonButton" BasedOn="{StaticResource ToolTipDefaults}"/>
<Style TargetType="RibbonToggleButton" BasedOn="{StaticResource ToolTipDefaults}"/>
<Style TargetType="RibbonDropDownButton" BasedOn="{StaticResource ToolTipDefaults}"/>
Ограничением этого подхода является то, что стиль может быть основан только на одном родительском стиле, поэтому, если вы уже используете этот шаблон, вы не сможете этого сделать.
Я столкнулся с той же проблемой и нашел заметное решение. На самом деле их два.
Оба они основаны на системе метаданных DependencyProperty. Для них обоих вам понадобится довольно похожий код статической инициализации:
public static class ToolTipServiceHelper
{
static ToolTipServiceHelper()
{
ToolTipService.InitialShowDelayProperty
.OverrideMetadata(typeof(FrameworkElement),
new FrameworkPropertyMetadata(...));
}
}
Что используется вместо "..."?
Первое решение довольно очевидно: поместите туда желаемое значение по умолчанию, которое будет применяться ко всему приложению за исключением мест, где указывается фактическое значение.
Второе решение является непростым: вместо "..." вы предоставляете значение по умолчанию из метаданных по умолчанию, но помимо этого вы меняете параметры, на самом деле вам нужно сделать наследуемое свойство.
new FrameworkPropertyMetadata(
ToolTipService.InitialShowDelayProperty.DefaultMetadata.DefaultValue,
FrameworkPropertyMetadataOptions.Inherits)
Когда свойство является наследуемым, вы можете сделать следующее: