<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style xmlns:local2="using:ArticleApp.Controls.ExtendedTextBox" TargetType="local2:ExtendedTextBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local2:ExtendedTextBox"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="using:ArticleApp.Controls"> <Style TargetType="controls:ExtendedTextBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="controls:ExtendedTextBox"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
<Page x:Class="ArticleApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="using:ArticleApp.Controls"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <controls:ExtendedTextBox HorizontalAlignment="Center" VerticalAlignment="Center" Width="200" Height="40" BorderBrush="Red" BorderThickness="2"/> </Grid> </Page>
<StackPanel Grid.Row="0" Grid.ColumnSpan="2" Orientation="Horizontal" Margin="0,0,0,8"> <ContentPresenter x:Name="HeaderContentPresenter" x:DeferLoadStrategy="Lazy" Visibility="Collapsed" Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}" Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" FontWeight="Normal" /> <TextBlock x:Name="NecessityIndicatorTextBlock" Text="*" FontSize="{TemplateBinding FontSize}" Foreground="Red" Visibility="{TemplateBinding IsNecessarily}"/> </StackPanel>
public sealed class ExtendedTextBox : TextBox { private TextBlock _necessityIndicatorTextBlock; public ExtendedTextBox() { this.DefaultStyleKey = typeof(ExtendedTextBox); } protected override void OnApplyTemplate() { base.OnApplyTemplate(); _necessityIndicatorTextBlock = GetTemplateChild("NecessityIndicatorTextBlock") as TextBlock; UpdateControl(); } public bool IsNecessarily { get => (bool)GetValue(IsNecessarilyProperty); set => SetValue(IsNecessarilyProperty, value); } public static readonly DependencyProperty IsNecessarilyProperty = DependencyProperty.Register("IsNecessarily", typeof(bool), typeof(ExtendedTextBox), new PropertyMetadata(false, IsNecessarilyPropertyChanged)); private static void IsNecessarilyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var textbox = d as ExtendedTextBox; if (textbox == null || !(e.NewValue is bool)) { return; } textbox.UpdateNecessityIndicator(); } private void UpdateControl() { UpdateNecessityIndicator(); } private void UpdateNecessityIndicator() { if (_necessityIndicatorTextBlock != null) { _necessityIndicatorTextBlock.Visibility = IsNecessarily ? Visibility.Visible : Visibility.Collapsed; } } }
public sealed class ExtendedTextBox : TextBox { private TextBlock _necessityIndicatorTextBlock; public ExtendedTextBox() ... protected override void OnApplyTemplate() { base.OnApplyTemplate(); this.TextChanged -= ExtendedTextBoxTextChanged; _necessityIndicatorTextBlock = GetTemplateChild("NecessityIndicatorTextBlock") as TextBlock; this.TextChanged += ExtendedTextBoxTextChanged; UpdateControl(); } private void ExtendedTextBoxTextChanged(object sender, TextChangedEventArgs e) { ValidateTextBox(); } //public bool IsNecessarily ... //public static readonly DependencyProperty IsNecessarilyProperty = ... //private static void IsNecessarilyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) ... public string RegexPattern { get { return (string)GetValue(RegexPatternProperty); } set { SetValue(RegexPatternProperty, value); } } public static readonly DependencyProperty RegexPatternProperty = DependencyProperty.Register("RegexPattern", typeof(string), typeof(ExtendedTextBox), new PropertyMetadata(string.Empty, RegexPatternPropertyChanged)); private static void RegexPatternPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var textbox = d as ExtendedTextBox; if (textbox == null || !(e.NewValue is string)) { return; } textbox.ValidateTextBox(); } private void ValidateTextBox() { IsValid = Regex.IsMatch(Text, RegexPattern); if (this.Text.Length == 0 || !this.IsValid.HasValue) { VisualStateManager.GoToState(this, "Indeterminate", true); return; } VisualStateManager.GoToState(this, this.IsValid.Value ? "Valid" : "Invalid", true); } public bool? IsValid { get { return (bool?)GetValue(IsValidProperty); } private set { SetValue(IsValidProperty, value); } } public static readonly DependencyProperty IsValidProperty = DependencyProperty.Register("IsValid", typeof(bool?), typeof(ExtendedTextBox), new PropertyMetadata(default(bool?))); private void UpdateControl() { UpdateNecessityIndicator(); ValidateTextBox(); } //private void UpdateNecessityIndicator() ... }
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="5" /> <ColumnDefinition Width="16" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Border x:Name="BackgroundElement"/> <Border x:Name="BorderElement"/> <StackPanel Grid.Row="0" Grid.ColumnSpan="2" Orientation="Horizontal" Margin="0,0,0,8"> <ContentPresenter x:Name="HeaderContentPresenter"/> <TextBlock x:Name="NecessityIndicatorTextBlock"/> </StackPanel> <ScrollViewer x:Name="ContentElement"/> <ContentControl x:Name="PlaceholderTextContentPresenter"/> <Button x:Name="DeleteButton"/> <Image x:Name="ValidationStatusImage" Grid.Row="1" Grid.Column="3"/> </Grid>
<VisualStateGroup x:Name="ValidStates"> <VisualState x:Name="Indeterminate"/> <VisualState x:Name="Valid"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationStatusImage" Storyboard.TargetProperty="Source"> <DiscreteObjectKeyFrame KeyTime="0" Value="Assets/Icons/validState.png" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Invalid"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationStatusImage" Storyboard.TargetProperty="Source"> <DiscreteObjectKeyFrame KeyTime="0" Value="Assets/Icons/invalidState.png" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup>
public partial class Expander { public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(nameof(Header), typeof(string), typeof(Expander), new PropertyMetadata(null)); public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register(nameof(IsExpanded), typeof(bool), typeof(Expander), new PropertyMetadata(false, OnIsExpandedPropertyChanged)); public string Header { get { return (string)GetValue(HeaderProperty); } set { SetValue(HeaderProperty, value); } } public bool IsExpanded { get { return (bool)GetValue(IsExpandedProperty); } set { SetValue(IsExpandedProperty, value); } } }
public sealed partial class Expander : ContentControl { public Expander() { this.DefaultStyleKey = typeof(Expander); } protected override void OnApplyTemplate() { base.OnApplyTemplate(); if (IsExpanded) { VisualStateManager.GoToState(this, "Expanded", true); } } private void ExpandControl() { VisualStateManager.GoToState(this, "Expanded", true); } private void CollapseControl() { VisualStateManager.GoToState(this, "Collapsed", true); } private static void OnIsExpandedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var expander = d as Expander; bool isExpanded = (bool)e.NewValue; if (isExpanded) { expander.ExpandControl(); } else { expander.CollapseControl(); } } }
<Style TargetType="controls:Expander"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="controls:Expander"> <Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="ExpandedStates"> <VisualState x:Name="Expanded"> <VisualState.Setters> <Setter Target="MainContent.Visibility" Value="Visible" /> </VisualState.Setters> </VisualState> <VisualState x:Name="Collapsed" /> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <ToggleButton x:Name="ExpanderToggleButton" Height="40" HorizontalContentAlignment="Left" HorizontalAlignment="Stretch" Foreground="{TemplateBinding Foreground}" Content="{TemplateBinding Header}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" /> <ContentPresenter Grid.Row="1" x:Name="MainContent" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="Stretch" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Visibility="Collapsed" /> </Grid> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
Source: https://habr.com/ru/post/335240/
All Articles