首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Xamarin表格画线?

如何用Xamarin表格画线?
EN

Stack Overflow用户
提问于 2018-02-23 13:01:43
回答 1查看 3.4K关注 0票数 0

我正在创建一个交叉平台应用程序的Xamarin表单,并试图绘制从10-10使用下面的代码线。但问题是,这条线只从10画到0。我不知道为什么会发生这种事。

代码语言:javascript
复制
int margin = 20;
int steps = 20;

float start = margin;
float end = width - margin;

float dHeigth = heigth - (margin * 4);
float hStep = dHeigth / Convert.ToSingle(steps);

float textMargin = 30;

// draw the line
for (int i = 10; i >= -10; i--)
{
    float xpoint = i * hStep + margin;

    if (i.IsOdd())
    {
        canvas.DrawLine(start + textMargin, xpoint, end, xpoint, LineWhitePaint);
    }
    else
    {
        decimal dText = 0;
        canvas.DrawLine(start + textMargin, xpoint, end, xpoint, LineGreyPaint);
        if (i < 0)
            dText = i;
        else
            dText = (10 - i);
        string txt = dText.ToString();

        canvas.DrawText(txt, start + margin, xpoint + 15, TextStyleFillPaintX);
    }
}

我在附加屏幕截图

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-23 14:56:50

对于正行,您正在绘制10 - i,这将生成第一次迭代的0,第三次迭代的2等等。关于这个,你可以看到,你已经开始从画布的中间画线了。第十次迭代将画出最上面的一条线(第10条)。还画了更多的线,但没有在屏幕上画。

在将xPoint写入调试输出时,您也可以看到这一点。当i变得负值时,xPoint也会。要解决这个问题,您必须偏移xPoint才能始终在屏幕上绘图

代码语言:javascript
复制
float xpoint = i * hStep + margin + steps / 2 * hStep;

或者,您可以从20循环到0,并更改文本的生成方式。

代码语言:javascript
复制
for (int i = 20; i >= 0; i--)
{
    var xPoint = i * hStep + margin;

    // ...

    var displayedText = GetDisplayedText(i, steps);

    // ...
}

string GetDisplayedText(int i, int steps)
{
    var displayedValue = i > steps / 2 
        ? steps - i
        : -i - steps / 2; // I think this should be the formula
    return displayedValue.ToString();
}

备注:更好的做法是封装行的概念,将它们的计算与绘制分开。您可以创建一个工厂,根据索引和步骤数生成正确的行,然后只对Line对象进行迭代,并通过传递画布绘制它们。这将使您的代码更加简洁和整洁。

更新

既然我们已经澄清了要求,我会再试一次。

首先,我定义了将图形坐标转换为画布坐标的方法

代码语言:javascript
复制
private SKPoint ToCanvasCoordinates(SKPoint graphCoordinates)
{
    var x = Margin + TextMargin + (_canvas.Width - 2*Margin - TextMargin)*graphCoordinates.X;
    var y = (MaxY - graphCoordinates.Y)*(_canvas.Height - 2 * Margin)/(MaxY - MinY) + Margin;

    return new SKPoint(x,y);
}

private SKPoint GetLegendCoordinates(int i)
{
    var x = Margin;
    var y = (MaxY - graphCoordinates.Y)*(_canvas.Height - 2 * Margin)/(MaxY - MinY) + Margin + 15;

    return new SKPoint(x,y);
}

在本例中,_canvas是私有成员字段,MarginMaxYMinY是属性。我假设x的最小值为0,最大值为1。

现在你可以画你的线了

代码语言:javascript
复制
for(int i = -1; i <= 10; i++)
{
    var lineStart = ToCanvasCoordinates(new SKPoint(0, i));
    var lineEnd = ToCanvasCoordinates(new SKPoint(1, i));

    canvas.DrawLine(lineStart, lineEnd, LineGreyPaint);

    var textPosition = GetLegendCoordinates(i);

    canvas.DrawText(i.ToString(), textPosition, TextStyleFillPaintX);
}

此外,如果您想在两条网格线之间画一条线,可以使用以下方法

代码语言:javascript
复制
private void DrawDataLine(SKPoint start, SKPoint end, SKPaint paint)
{
    var startTransformed = ToCanvasCoordinates(start);
    var endTransformed = ToCanvasCoordinates(end);

    _canvas.DrawLine(startTransformed, endTransformed, paint);
}

private void DrawData(SKPaint paint)
{
    for(int i=1; i<_data.Length; i++)
    {
        DrawDataLine(new SKPoint(data[i-1].X, data[i-1].Y), new SKPoint(data[i].X, data[i].Y)); // given that the objects in _data have the properties X and Y
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48948532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档