Question

I have a set of data templates I am using for my custom control. It works well, but I want to be able to bind it to data and have values scale based on the min / max of the set. I have created the following value converter:

    public class ScaleValueConverter : IValueConverter
{
    /// <summary>
    /// The property to use the value of
    /// </summary>
    public string ValueProperty { get; set; }

    /// <summary>
    /// The minimum value to be scaled against. Will become 0%
    /// </summary>
    public int MinValue { get; set; }

    /// <summary>
    /// The maximum value to be scaled against. Will become 100%.
    /// </summary>
    public int MaxValue { get; set; }


    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var type = value.GetType();
        var property = type.GetProperty(ValueProperty);

        if (property == null)
            return 0;

        var result = System.Convert.ToDecimal(property.GetValue(value, null));

        //TODO: Scale stuff

        return result + 100;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

The aim is to have a generic value converter, and simply supply the binding source object, to the value converter in the XAML, and have it sort things out.

I'm not sure how to do this however, as I am unable to access the value converter I have created from my templated control.

I'm looking for something that would work roughly as follows:

        public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        //Get Value Converters
        var topScaleValueConverter = GetTemplateChild("TopScaleValueConverter");
        var bottomScaleValueConverter = GetTemplateChild("BottomScaleValueConverter");

        //Setup value converter Min / Max / ValueProperty here
    }

Ideally they would be parts of my template, and I could extract them as parts, but that doesn't appear to work.

Can anyone point me in the right direction for getting this type of behavior working?

Regards

Tristan

EDIT: I suppose it would be nice to be able to dependency inject them. Does anyone know if this is possible?

Was it helpful?

Solution

Derive ScaleValueConverter from DependDencyObject and implement your properties as Dependency Properties.

  public class ScaleValueConverter : DependencyObject, IValueConverter
    {

        public double MinValue
        {
            get { return (double)GetValue(MinValueProperty); }
            set { SetValue(MinValueProperty, value); }
        }

        public static readonly DependencyProperty MinValueProperty =
            DependencyProperty.Register("MinValue", typeof(double), typeof(ScaleValueConverter), new PropertyMetadata(0.0d));


        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double result = double.Parse(value.ToString())

            if (result < MinValue)
            {
                result = MinValue;
            }

          return result;
        }
    }

You will then be able to "inject" data into your properties via a VM.

<ns:ScaleValueConverter x:Key="scaleValue" MinValue="{Binding MinValue,Source={StaticResource MyModelSource}" />

In short, treat your converter the same as any other dependency object and bind as usual.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top