簡體   English   中英

如何以Xamarin形式繪制線條?

[英]How to Draw Lines in Xamarin Forms?

我正在Xamarin表單中創建一個跨平台應用程序,並嘗試使用以下代碼在10到-10之間繪制線條。 但是問題是線條僅從10繪制到0。 為什么會這樣,我沒有任何想法。

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);
    }
}

我附上了那個的屏幕截圖

截圖

對於正線,您將繪制10 - i ,第一次迭代的結果為0 ,第三次迭代的結果為2 ,依此類推。 關於這一點,您可以看到,您正在開始從畫布的中間繪制線條。 第十次迭代將繪制最上面的線(帶有10的那一行)。 進一步繪制,而不是在屏幕上。

在將xPoint寫入調試輸出時,您也可以看到這一點。 i變得負面時, xPoint也將如此。 要解決此問題,您必須偏移xPoint才能始終在屏幕上繪制

float xpoint = i * hStep + margin + steps / 2 * hStep;

或者,您可以從20循環到0,並更改文本的生成方式。

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對象進行迭代,並通過傳遞畫布來繪制它們。 這將使您的代碼更加整潔。

UPDATE

由於我們已經能夠闡明要求,因此我將再提出一個建議。

首先,我將定義將圖形坐標轉換為畫布坐標的方法

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。

現在您可以像

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);
}

此外,如果您想在兩條網格線之間畫一條線,則可以使用以下方法

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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM