2017-09-29 3 views
0

Bei dem Versuch, die Farbe der PlaceholderText in einem Text zu binden, habe ich gewählt, um die Vorlage in einen Stil zu versuchen, platzieren wir ändern können:UWP Bindung des TextBox PlaceholderTextContentPresenter Vordergrunds auf eine Eigenschaft in dem viewmdoel Usercontrol

<Style x:Key="TextBoxStyle" TargetType="TextBox"> 
    <Setter Property="Template"> 
... 
<ContentPresenter x:Name="PlaceholderTextContentPresenter" Foreground="{Binding HintTextColor}" /> 

Mein Usercontrol:

<UserControl x:Name="This" 
    <TextBox 
     Style="{StaticResource TextBoxStyle}" 
     x:Name="_textBox" 
    /> 
/> 

ich habe versucht, Variationen:

Foreground="{Binding DataContext.HintTextColor, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}}" 

Auch versucht (keine verbindlichen Fehler)

<ContentPresenter x:Name="PlaceholderTextContentPresenter" Foreground="{Binding ElementName=This.DataContext.HintTextColor}" /> 

Der Versuch, den Vordergrund auf die richtige Datacontext und Farbeigenschaften zu verbinden, aber entweder die Syntax nur in WPF unterstützt wird oder ich bekomme eine Bindung Fehler in der Ausgabe. Wie binde ich den Vordergrund an das Steuerelement Ansichtsmodell HintTextColor?

bearbeiten

Die endgültige Lösung, wie dies für mich aussieht:

<UserControl 
    <customControlsUwp:CustomTextBox 
     PlaceholderForeground="{Binding HintTextColor, Converter={StaticResource StringColorToBrushConverter}}" 
    /> 
/> 

public sealed class CustomTextBox : TextBox { 
    public CustomTextBox() { 
     DefaultStyleKey = typeof(CustomTextBox); 
    } 

    private ContentPresenter _placeholderTextContentPresenter; 

    public SolidColorBrush PlaceholderForeground { 
     get => (SolidColorBrush)GetValue(PlaceholderForegroundProperty); 
     set => SetValue(PlaceholderForegroundProperty, value); 
    } 

    //Add DP PlaceholderForeground for runtime bound changes to HintTextColor 
    public static readonly DependencyProperty PlaceholderForegroundProperty = 
     DependencyProperty.Register("PlaceholderForeground", typeof(SolidColorBrush), typeof(CustomTextBox), new PropertyMetadata(null, PropertyChangedCallback)); 


    public static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { 

     if (!(d is CustomTextBox customTextBox) || !(e.NewValue is SolidColorBrush solidColorBrush)) 
      return; 

     if (customTextBox._placeholderTextContentPresenter == null) 
      customTextBox._placeholderTextContentPresenter.Foreground = solidColorBrush; 
    } 

    protected override void OnApplyTemplate() { 
     base.OnApplyTemplate(); 
     _placeholderTextContentPresenter = GetTemplateChild("PlaceholderTextContentPresenter") as ContentPresenter; 
    } 
} 

und hat eine Vorlage in der Steuer Stil Bindung des ersten Wertesatz zu erfassen:

<ContentPresenter x:Name="PlaceholderTextContentPresenter" Foreground="{TemplateBinding PlaceholderForeground}" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" IsHitTestVisible="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" TextWrapping="{TemplateBinding TextWrapping}"/> 

Antwort

1

UWP unterstützt keine Bindung im Stil. Sie können die Migration Hinweise Abschnitt in MSDN document sehen.

Sie könnten eine benutzerdefinierte TextBox erstellen und eine Abhängigkeitseigenschaft mit dem Namen PlaceholderForeground definieren. In der Überschreibungsmethode OnApplyTemplate können Sie das ContentPresenter-Steuerelement "PlaceholderTextContentPresenter" aus der Vorlage seines Standardstils abrufen. Wenn Ihre Abhängigkeitseigenschaft geändert wird, können Sie den neuen Wert auf "PlaceholderTextContentPresenter" .Foreground festlegen.

public class CustomTextBox : TextBox 
{ 
    private ContentPresenter _PlaceholderTextContentPresenter; 

    public SolidColorBrush PlaceholderForeground 
    { 
     get { return (SolidColorBrush)GetValue(PlaceholderForegroundProperty); } 
     set { SetValue(PlaceholderForegroundProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty PlaceholderForegroundProperty = 
     DependencyProperty.Register("PlaceholderForeground", typeof(SolidColorBrush), typeof(CustomTextBox), new PropertyMetadata(null, PropertyChangedCallback)); 


    public static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     if ((d as CustomTextBox)._PlaceholderTextContentPresenter !=null) 
     { 
      (d as CustomTextBox)._PlaceholderTextContentPresenter.Foreground = e.NewValue as SolidColorBrush; 
     } 
    } 

    protected override void OnApplyTemplate() 
    { 
     _PlaceholderTextContentPresenter = GetTemplateChild("PlaceholderTextContentPresenter") as ContentPresenter; 
    } 

    public CustomTextBox() 
    { 
     DefaultStyleKey = typeof(CustomTextBox); 

    } 
} 
<Application 
x:Class="AppUsercontrol.App" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:AppUsercontrol" 
RequestedTheme="Light"> 
<Application.Resources> 
    <Style x:Key="CustomTextBoxStyle1" TargetType="local:CustomTextBox"> 
     <Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}"/> 
     <Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}"/> 
     <Setter Property="Foreground" Value="{ThemeResource TextControlForeground}"/> 
     <Setter Property="Background" Value="{ThemeResource TextControlBackground}"/> 
     <Setter Property="BorderBrush" Value="{ThemeResource TextControlBorderBrush}"/> 
     <Setter Property="SelectionHighlightColor" Value="{ThemeResource TextControlSelectionHighlightColor}"/> 
     <Setter Property="BorderThickness" Value="{ThemeResource TextControlBorderThemeThickness}"/> 
     <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/> 
     <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/> 
     <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto"/> 
     <Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/> 
     <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/> 
     <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/> 
     <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/> 
     <Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="local:CustomTextBox"> 
        <Grid> 
         <Grid.Resources> 
          <Style x:Name="DeleteButtonStyle" TargetType="Button"> 
           <Setter Property="Template"> 
            <Setter.Value> 
             <ControlTemplate TargetType="Button"> 
              <Grid x:Name="ButtonLayoutGrid" BorderBrush="{ThemeResource TextControlButtonBorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{ThemeResource TextControlButtonBackground}"> 
               <VisualStateManager.VisualStateGroups> 
                <VisualStateGroup x:Name="CommonStates"> 
                 <VisualState x:Name="Normal"/> 
                 <VisualState x:Name="PointerOver"> 
                  <Storyboard> 
                   <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonLayoutGrid"> 
                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPointerOver}"/> 
                   </ObjectAnimationUsingKeyFrames> 
                   <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonLayoutGrid"> 
                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPointerOver}"/> 
                   </ObjectAnimationUsingKeyFrames> 
                   <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement"> 
                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPointerOver}"/> 
                   </ObjectAnimationUsingKeyFrames> 
                  </Storyboard> 
                 </VisualState> 
                 <VisualState x:Name="Pressed"> 
                  <Storyboard> 
                   <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonLayoutGrid"> 
                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPressed}"/> 
                   </ObjectAnimationUsingKeyFrames> 
                   <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonLayoutGrid"> 
                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPressed}"/> 
                   </ObjectAnimationUsingKeyFrames> 
                   <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement"> 
                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPressed}"/> 
                   </ObjectAnimationUsingKeyFrames> 
                  </Storyboard> 
                 </VisualState> 
                 <VisualState x:Name="Disabled"> 
                  <Storyboard> 
                   <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ButtonLayoutGrid"/> 
                  </Storyboard> 
                 </VisualState> 
                </VisualStateGroup> 
               </VisualStateManager.VisualStateGroups> 
               <TextBlock x:Name="GlyphElement" AutomationProperties.AccessibilityView="Raw" Foreground="{ThemeResource TextControlButtonForeground}" FontStyle="Normal" FontSize="12" FontFamily="{ThemeResource SymbolThemeFontFamily}" HorizontalAlignment="Center" Text="&#xE10A;" VerticalAlignment="Center"/> 
              </Grid> 
             </ControlTemplate> 
            </Setter.Value> 
           </Setter> 
          </Style> 
         </Grid.Resources> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="*"/> 
          <ColumnDefinition Width="Auto"/> 
         </Grid.ColumnDefinitions> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="*"/> 
         </Grid.RowDefinitions> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualState x:Name="Disabled"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="HeaderContentPresenter"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlHeaderForegroundDisabled}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BorderElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundDisabled}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushDisabled}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundDisabled}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundDisabled}"/> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Normal"/> 
           <VisualState x:Name="PointerOver"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushPointerOver}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BorderElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundPointerOver}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundPointerOver}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundPointerOver}"/> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Focused"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundFocused}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BorderElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocused}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushFocused}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundFocused}"/> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="RequestedTheme" Storyboard.TargetName="ContentElement"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="Light"/> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
          </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="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1"/> 
         <ContentPresenter x:Name="HeaderContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{ThemeResource TextControlHeaderForeground}" FontWeight="Normal" Margin="0,0,0,8" Grid.Row="0" TextWrapping="{TemplateBinding TextWrapping}" Visibility="Collapsed" x:DeferLoadStrategy="Lazy"/> 
         <ScrollViewer x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled"/> 
         <ContentPresenter x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" IsHitTestVisible="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" TextWrapping="{TemplateBinding TextWrapping}"/> 
         <Button x:Name="DeleteButton" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" FontSize="{TemplateBinding FontSize}" IsTabStop="False" Margin="{ThemeResource HelperButtonThemePadding}" MinWidth="34" Grid.Row="1" Style="{StaticResource DeleteButtonStyle}" Visibility="Collapsed" VerticalAlignment="Stretch"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Application.Resources> 

+0

ich diesen Code in eine neue Klassenbibliotheksprojekt für benutzerdefinierte Steuerelemente platziert haben. Ich kann das neue Steuerelement von meinem Hauptprojekt referenzieren - PropertyChangedCallback wird aufgerufen, aber die OnApplyTemplate-Überschreibung wird nie aufgerufen und der _PlaceholderTextContentPresenter ist immer null – jchristof

+0

Clean Build scheint das behoben zu haben - ich musste auch eine Template-Bindung im Foreground hinzufügen ContentPresenter für den PlaceholderText, um den Anfangswert von der VM zu erfassen - Ich werde meinen Beitrag mit dieser Information aktualisieren. Danke vielmals! – jchristof

Verwandte Themen