From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

WPF custom ValueFormatter fails in 2015

Solved!
Go to solution

This code worked at MS 2013:

 

public class MyGeneralValueFormatter : GeneralValueFormatter
{

return Engineering.ToFormattedString(Convert.ToDouble(value), this.Format, _units);

}

protected override UIElement VisualizeCore<TData>(TData value, ValuePresenterArgs args, UIElement existingVisual)
{
UIElement element = base.VisualizeCore<TData>(value, args, existingVisual);

if (args.Context is Axis<TData>)
{
var axis = (Axis<TData>)args.Context;

if (axis.Orientation == System.Windows.Controls.Orientation.Horizontal)
{
if (_showOnlyMinMaxAtX)
{
Range<TData> range = axis.Range;
var comparer = range.Comparer;
RelativeAlignment alignment =
comparer.Compare(range.Minimum, value) == 0 ? RelativeAlignment.Near :
comparer.Compare(range.Maximum, value) == 0 ? RelativeAlignment.Far :
RelativeAlignment.Center;
//RegionPanel.SetRelativeHorizontalAlignment(element, alignment);

element.Opacity = comparer.Compare(range.Minimum, value) == 0 || comparer.Compare(range.Maximum, value) == 0 ? 1.0 : 0.0;
}
}
else
{
element = new Viewbox { MaxWidth = 60, Width = 60, Stretch = System.Windows.Media.Stretch.None, Child = element };
}
}

return element;
}
}

 

 

 

 

1. This doesn't even compile:

RegionPanel.SetRelativeHorizontalAlignment(element, alignment);

 

2. This crashes with error: Specified element is already the logical child of another element. Disconnect it first.

element = new Viewbox { MaxWidth = 60, Width = 60, Stretch = System.Windows.Media.Stretch.None, Child = element };

0 Kudos
Message 1 of 4
(4,480 Views)

Hi, eugenem

 

I can address one of your concerns immediately. In Measurement Studio 2015, RegionPanel was changed to RelativePanel, which is why that line no longer compiles.

 

To address your other concern, I will need more context for this code. Syntactically, I don't believe your code (as is) would have compiled in any version of Visual Studio. It is also unclear how the value formatter class relates to the VisualizeCore<TData> override method. Can you please provide a more complete snippet? Please see the following copy of the code you provided, where I have added comments with questions. I also highlighted the place I changed RegionPanel to RelativePanel.

 

// This is a class definition. Why is it returning a value?
public class MyGeneralValueFormatter : GeneralValueFormatter
{
    return Engineering.ToFormattedString(Convert.ToDouble(value), this.Format, _units);
}

// Where does this method belong? Currently it does not have a containing class.
protected override UIElement VisualizeCore<TData>(TData value, ValuePresenterArgs args, UIElement existingVisual)
{
    UIElement element = base.VisualizeCore<TData>(value, args, existingVisual);

    if (args.Context is Axis<TData>)
    {
        var axis = (Axis<TData>)args.Context;
        if (axis.Orientation == System.Windows.Controls.Orientation.Horizontal)
        {
            if (_showOnlyMinMaxAtX)
            {
                Range<TData> range = axis.Range;
                var comparer = range.Comparer;
                RelativeAlignment alignment =
                comparer.Compare(range.Minimum, value) == 0 ? RelativeAlignment.Near :
                comparer.Compare(range.Maximum, value) == 0 ? RelativeAlignment.Far :
                RelativeAlignment.Center;
                RelativePanel.SetRelativeHorizontalAlignment(element, alignment);
                element.Opacity = comparer.Compare(range.Minimum, value) == 0 || comparer.Compare(range.Maximum, value) == 0 ? 1.0 : 0.0;
            }
        }
        else
        {
            element = new Viewbox { MaxWidth = 60, Width = 60, Stretch = System.Windows.Media.Stretch.None, Child = element };
        }
    }

    return element;
}
}
Daniel Dorroh
National Instruments
0 Kudos
Message 2 of 4
(4,474 Views)

sorry, I've deleted too much of the class. there is the full version:

 

  public class RCAGeneralValueFormatter : GeneralValueFormatter 
  {
    private string _units;
    private bool _showOnlyMinMaxAtX;

    public RCAGeneralValueFormatter(string format, string units, bool showOnlyMinMaxAtX)
      : base(format)
    {
      _units = units;
      _showOnlyMinMaxAtX = showOnlyMinMaxAtX;
    }

    protected override string FormatCore<TData>(TData value, ValuePresenterArgs args)
    {
      if (args.Context is Axis<TData>)
      {
        var axis = (Axis<TData>)args.Context;

        if (axis.Orientation == System.Windows.Controls.Orientation.Horizontal)
        {
            Range<TData> range = axis.Range;
            var comparer = range.Comparer;
            if( comparer.Compare(range.Minimum, value) != 0 && comparer.Compare(range.Maximum, value) != 0)
              return Engineering.ToFormattedString(Convert.ToDouble(value), this.Format, "");
        }
      }
      
      return Engineering.ToFormattedString(Convert.ToDouble(value), this.Format, _units);
    }

    protected override UIElement VisualizeCore<TData>(TData value, ValuePresenterArgs args, UIElement existingVisual)
    {
      UIElement element = base.VisualizeCore<TData>(value, args, existingVisual);
        
      if (false && args.Context is Axis<TData>)
      {
        var axis = (Axis<TData>)args.Context;

        if (axis.Orientation == System.Windows.Controls.Orientation.Horizontal)
        {
          if (_showOnlyMinMaxAtX)
          {
            Range<TData> range = axis.Range;
            var comparer = range.Comparer;
            RelativeAlignment alignment =
                    comparer.Compare(range.Minimum, value) == 0 ? RelativeAlignment.Near :
                    comparer.Compare(range.Maximum, value) == 0 ? RelativeAlignment.Far :
                    RelativeAlignment.Center;
            //RegionPanel.SetRelativeHorizontalAlignment(element, alignment);

            element.Opacity = comparer.Compare(range.Minimum, value) == 0 || comparer.Compare(range.Maximum, value) == 0 ? 1.0 : 0.0;
          }
        }
        else
        {
          element = new Viewbox { MaxWidth = 60, Width = 60, Stretch = System.Windows.Media.Stretch.None, Child = element };
        }
      }
        
      return element;
    }
  }
0 Kudos
Message 3 of 4
(4,472 Views)
Solution
Accepted by topic author eugenem

Thank you for posting the rest of the code.

 

It looks like instead of using your override for VisualizeCore<TData>, you can make use of the new properties, RangeLabeledDivisions.MaximumLabelAlignment and RangeLabeledDivisions.MinimumLabelAlignment. For example:

 

<ni:Graph>
    <ni:Graph.Axes>
        <ni:AxisDouble Orientation="Horizontal">
            <ni:AxisDouble.MajorDivisions>
                <ni:RangeLabeledDivisions MaximumLabelAlignment="Far" MinimumLabelAlignment="Near" />
            </ni:AxisDouble.MajorDivisions>
        </ni:AxisDouble>
    </ni:Graph.Axes>
</ni:Graph>

 

As for creating a new ViewBox, is there a reason you don't just set the UIElement properties directly on element? It seems like setting the MaxWidth on element would have the same effect as what you are doing there.

Daniel Dorroh
National Instruments
0 Kudos
Message 4 of 4
(4,459 Views)