Salmy
Salmy

Reputation: 47

Set DependencyProperty's PropertyMetadata to a TextBox's inherited Foreground Color, FontSize

In the following c# wpf Code, I want to set the PropertyMetadata of the PlaceholderFontSize property to the inhereted TextBox's FontSize or Foreground The following code is a custom TextBox that has the Dependency_Properties :

 public class CustomTextBox : TextBox
    {
        public CustomTextBox() {
        }

        private SolidColorBrush _placeholderForeground;
        public SolidColorBrush PlaceholderForeground
        {
            get { return _placeholderForeground; }
            set { _placeholderForeground = value; }
        }

        public static readonly DependencyProperty PlaceholderForegroundProperty =
            DependencyProperty.Register("PlaceholderForeground", typeof(SolidColorBrush), typeof(CustomTextBox), new PropertyMetadata());

        private double _placeholderFontSize;
        public double PlaceholderFontSize
        {
            get { return _placeholderFontSize; }
            set { _placeholderFontSize = value; }
        }

        public static readonly DependencyProperty PlaceholderFontSizeProperty =
            DependencyProperty.Register("PlaceholderFontSize", typeof(double), typeof(CustomTextBox),new PropertyMetadata((double) 1));

    }

I have a Label as the templated child of this TextBox playing the role of a placeholder.
I want to set the DependencyProperty PlaceholderFontSizeProperty value to the templatedParent TextBox's FontSize
If the PlaceholderFontSizeProperty is not already set
And the same for PlaceholderForegroundProperty

this is the Label's Xaml Code :

<Label
       x:Name="PlaceHolder"
       Content="{TemplateBinding Tag}"
       FontWeight="{Binding PlaceholderFontWeight,RelativeSource={RelativeSource TemplatedParent}}"
       Foreground="{Binding PlaceholderForeground,RelativeSource={RelativeSource TemplatedParent}}"
       Background="Transparent"
       VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
       HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
       Visibility="Collapsed"
       Grid.Column="1">
   <Label.FontSize>
   <!-- A solution for FontSize using IMultiValueConverter -->
       <MultiBinding Converter="{StaticResource ComparisonConverter}" ConverterParameter="1">
           <Binding Path="PlaceholderFontSize" RelativeSource="{RelativeSource TemplatedParent}"/>
           <Binding Path="FontSize" RelativeSource="{RelativeSource TemplatedParent}"/>
       </MultiBinding>
   </Label.FontSize>
</Label>

I made a solution for the Fontsize using the following IMultiValueConverter By setteing to PropertyMetadata a (double) 1

public class ComparisonConverter : IMultiValueConverter
{
    private object PerformTypeConversion(object value,Type convertType)
    {
        if (convertType.IsAssignableFrom(value.GetType()))
        {
            return value;
        }
        else
        {
            try
            {
                value = System.Convert.ChangeType(value, convertType);
                return value;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        return null;
    }
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        //Set the values to the expected type
        object compareToParValue = PerformTypeConversion(values[0],targetType);
        object conditionValue = PerformTypeConversion(values[1], targetType);
        object condition = PerformTypeConversion(parameter, targetType);

        if(Equals(compareToParValue, condition))
        {
            return conditionValue;
        }
        return compareToParValue;
}

Upvotes: 0

Views: 42

Answers (1)

Salmy
Salmy

Reputation: 47

Here is a solution

public static readonly DependencyProperty PlaceholderForegroundProperty = DependencyProperty.Register(
    "PlaceholderForeground", typeof(SolidColorBrush), typeof(CustomTextBox),
    new PropertyMetadata(null, PlaceholderForegroundPropertyChanged));

//To display the changes in realtime
private static void PlaceholderForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    CustomTextBox textbox = (CustomTextBox) d;
    if (textbox.ReadLocalValue(PlaceholderForegroundProperty) == DependencyProperty.UnsetValue)
        textbox.SetValue(PlaceholderForegroundProperty, textbox.Foreground);
}
//To set the foreground to the templatedParent foreground if it's not alrady set in XAML
public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    if (ReadLocalValue(PlaceholderForegroundProperty) == DependencyProperty.UnsetValue)
        SetValue(PlaceholderForegroundProperty, Foreground);
}

Upvotes: 0

Related Questions