Комментарии 20
В WPF эта проблема решалась куда элегантнее через Multitrigger:
И никакие хендлеры не нужны. К сожалению, не могу сейчас проверить сам, доступен ли Multitrigger в XAML, который в WinRT.
<ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsKeyboardFocused" Value="false"/> <Condition Property="Text" Value="" /> </MultiTrigger.Conditions> <Setter TargetName="PART_ContentHost" Property="Visibility" Value="Hidden"/> <Setter TargetName="watermark" Property="Visibility" Value="Visible"/> </MultiTrigger> </ControlTemplate.Triggers>
И никакие хендлеры не нужны. К сожалению, не могу сейчас проверить сам, доступен ли Multitrigger в XAML, который в WinRT.
0
Я в самом начале статьи написал, что у ControlTemplate даже Triggers отобрали…
+1
А триггеры из Microsoft.Expression.Interactivity не подойдут?
0
Это вы Placeholder вотермарком обозвали? оО
+2
я обычно так делаю:
<TextBox x:Name="SearchBox"/>
<TextBlock IsHitTestVisible="False"
Text="watermark"
Visibility="{Binding Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=SearchBox}" />
0
Вот такая ошибка
0
Хмммммм. И что, в WinRT нельзя банально переопределить стиль контрола переписав его шаблон (типа как тут msdn.microsoft.com/en-us/library/ms752068(v=vs.85).aspx)? Нужно обязательно городить такой огород аж с 2мя экземплярами TextBox? Зачем было TextBox делать базовым классом, если свойства вложенного TextBox'а никак не привязаны к родительскому, кроме тектса?
0
Template переопределить можно, но, как написано в начале статьи, и во втором комментарии от начала, ControlTemplate очень сильно порезали.
По поводу свойств согласен, хотел даже про это писать… Но, т.к. про то, как прокинуть текст во внутренний контрол написал, подумал, что все остальные свойства, которые понадобятся, догадаются, что они прокидываются также.
По поводу свойств согласен, хотел даже про это писать… Но, т.к. про то, как прокинуть текст во внутренний контрол написал, подумал, что все остальные свойства, которые понадобятся, догадаются, что они прокидываются также.
0
Ну можно было про это строчку текста написать. Но подход, конечно, опасный. Это ж сколько там привязок свойств? Вкладывать в один бокс другой… Можно ведь было, наверное, без триггеров и вложенных боксов. Точно так же, написать класс, производный от TextBox (не UserControl), переопределить стиль по умолчанию, написать шаблон, назвать его части типа PART_Watermark и т.д. и прицепиться к ним из OnApplyTemplate…
О, лол, первый результат поиска по «WinRT OnApplyTemplate»: elegantcode.com/2012/03/06/create-your-first-winrt-watermarktextbox-control/
Вот как надо было делать.
О, лол, первый результат поиска по «WinRT OnApplyTemplate»: elegantcode.com/2012/03/06/create-your-first-winrt-watermarktextbox-control/
Вот как надо было делать.
0
Угу, меня всегда радовали вот такие простыни кода в статьях с заголовком Create Your First <что-то там>:
Но за ссылку спасибо, посмотрю.
Много строк кода
<Style TargetType="local:WatermarkTextBox">
<Setter Property="MinWidth" Value="{StaticResource TextBoxMinWidth}"/>
<Setter Property="MinHeight" Value="{StaticResource TextBoxMinHeight}"/>
<Setter Property="Foreground" Value="{StaticResource TextBoxTextBrush}"/>
<Setter Property="Background" Value="{StaticResource TextBoxFillBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorderBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource InputControlBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource ContentFontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource ContentFontSize}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/>
<Setter Property="Padding" Value="{StaticResource TextBoxPaddingThickness}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:WatermarkTextBox">
<Grid>
<Grid.Resources>
<Style x:Name="DeleteButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonHoverFillBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonHoverBorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonHoverGlyphBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedFillBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedBorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedGlyphBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BorderElement" BorderBrush="{StaticResource TextBoxButtonBorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>
<Border x:Name="BackgroundElement" Background="{StaticResource TextBoxButtonFillBrush}" Margin="{TemplateBinding BorderThickness}">
<TextBlock x:Name="GlyphElement" Foreground="{StaticResource TextBoxButtonGlyphBrush}" FontFamily="Segoe UI Symbol" HorizontalAlignment="Center" Text="X" VerticalAlignment="Center"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledFillBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledBorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledTextBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimation Duration="0" To="{StaticResource TextBoxRestFillOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
<DoubleAnimation Duration="0" To="{StaticResource TextBoxRestBorderOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<DoubleAnimation Duration="0" To="{StaticResource TextBoxHoverFillOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
<DoubleAnimation Duration="0" To="{StaticResource TextBoxHoverBorderOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Focused"/>
</VisualStateGroup>
<VisualStateGroup x:Name="ButtonStates">
<VisualState x:Name="ButtonVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DeleteButton">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ButtonCollapsed"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BackgroundElement" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Margin="{TemplateBinding BorderThickness}"/>
<Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="2"/>
<ScrollViewer x:Name="ContentElement" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"/>
<Button x:Name="DeleteButton" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" FontSize="{TemplateBinding FontSize}" IsTabStop="False" Style="{StaticResource DeleteButtonStyle}" Visibility="Collapsed" VerticalAlignment="Stretch"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Но за ссылку спасибо, посмотрю.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Watermark для TextBox-а в Windows 8 приложениях