对齐左右垂直轴

Align left and right vertical axes

我有一个线系列连接到左边的垂直轴,另一个连接到右边的垂直轴。如何在两个轴上对齐 TicksGrids

原始状态:

如您所见,垂直轴的网格线位于不同的位置。我想如果我在两边设置相同数量的刻度,它可以对齐网格。我使用此代码:

private void AlignAxes()
{
   if (tChart1.Axes.Left.CalcIncrement != 0)
   {
      var ticksNum = (tChart1.Axes.Left.Maximum - tChart1.Axes.Left.Minimum) / 
                     tChart1.Axes.Left.CalcIncrement;
      tChart1.Axes.Right.Increment = 
                     (tChart1.Axes.Right.Maximum - tChart1.Axes.Right.Minimum) / ticksNum;
   }
}

但它没有按预期工作:

我想要这样的东西:

但显然具有正确计算和对齐的值。

解释:
我尝试了几乎所有可以想象到的方法并找到了解决方案(尽我所能)。结果至少对我来说已经足够好了。
我尝试的每项计算都不是 100% 有效。如果标签是自动创建的,则 Axis.Labels.Items 没有项目。最后我发现有名字为 labelPos 的 private ArrayList 并且在标签应该去的地方有矩形。所以我必须使用 System.Reflection 来获取这个列表。然后从这个矩形的位置计算另一个 y 轴上的值并将它们作为自定义标签插入。

代码:

private bool _redrawAgain = false;

private void AlignAxes()
{
    if (_redrawAgain)
    {
        _redrawAgain = false;
    }
    else
    {
        _redrawAgain = true;
        var tmpl = new AxisLabels(tChart1.Axes.Left);
        var privateField = tmpl.GetType().GetField("labelPos", 
                           BindingFlags.NonPublic | BindingFlags.Instance);
        var labelPos = (ArrayList)privateField.GetValue(tChart1.Axes.Left.Labels);

        tChart1.Axes.Right.Labels.Items.Clear();

        for (var i = 0; i < labelPos.Count; i++)
        {
            var rect = (Rectangle)labelPos[i];
            tChart1.Axes.Right.Labels.Items.Add(
                              tChart1.Axes.Right.CalcPosPoint(rect.Y + (rect.Height / 2)));
        }

        tChart1.Axes.Right.Grid.DrawEvery = tChart1.Axes.Left.Grid.DrawEvery;

        tChart1.Refresh();
    }
}

我从 TChart.AfterDraw 事件中调用 AlignAxes();,所以我必须再次刷新图表,但如果不从我尝试过的任何图表事件中刷新,我就无法正常工作。
此代码在运行时切换轴时也有效,即使左轴上没有任何内容,因为它只是从右轴清除自定义标签并让库关心标签。

结果:

我唯一没能解决的是 MinimumOffsetMaximumOffset,但我认为它在 TeeChart 库中被破坏了。我将两个轴上的两个偏移量都设置为 10,并且在显示图表时它们会正确显示,但是在缩放或滚动后,右轴上的标签会随着偏移量消失而左轴上的标签会消失,就好像有偏移量一样设置为 0。您可以在 x 轴附近的两个 y 轴上的图像上看到这种奇怪的行为 - 在左轴上有标签的直线上,右轴上没有标签。

更新:
我也想要轴标题,所以我不得不像这样更新代码:

private void AlignAxes(Graphics3D g)
{
    if (_redrawAgain)
    {
        _redrawAgain = false;
    }
    else
    {
        _redrawAgain = true;
        var tmpl = new AxisLabels(tChart1.Axes.Left);
        var privateField = tmpl.GetType().GetField("labelPos", 
                           BindingFlags.NonPublic | BindingFlags.Instance);
        var labels = (ArrayList)privateField.GetValue(tChart1.Axes.Left.Labels);

        tChart1.Axes.Right.Labels.Items.Clear();

        var gratestWidth = 0;

        for (var i = 0; i < labels.Count; i++)
        {
            var rect = (Rectangle)labels[i];
            tChart1.Axes.Right.Labels.Items.Add(
                              tChart1.Axes.Right.CalcPosPoint(rect.Y + (rect.Height / 2)));
            var width = g.MeasureString(tChart1.Axes.Right.Labels.Font, 
                        tChart1.Axes.Right.Labels.Items
                        [tChart1.Axes.Right.Labels.Items.Count - 1].
                        Value.ToString(
                        tChart1.Axes.Right.Labels.ValueFormat)).
                        ToSize().Width;
            if (width > gratestWidth)
            {
                gratestWidth = width;
            }
        }

        if (labels.Count > 0)
        {
            tChart1.Axes.Right.Labels.CustomSize = gratestWidth + 10;
        }
        else
        {
            tChart1.Axes.Right.Labels.CustomSize = 0;
        }

        tChart1.Axes.Right.Grid.DrawEvery = tChart1.Axes.Left.Grid.DrawEvery;

        tChart1.Refresh();
    }
}  

我不得不自己计算标签的宽度,否则会再次刷新图表。