我在c#(3周)中相当新,而StackOverflow虽然通过搜索找不到任何可以满足我在这个页面中的答案。
如何在c#中绘制x ^ 2函数(显然我只对x ^ 2感兴趣,但我选择的任何函数都不感兴趣)
这应该作为用户应用程序在网格中绘制。在此之前,我需要从用户选择自己的二进制文件中收集一些数据,并假设将这些点传递给数组,以便我能够绘制图形。
我不熟悉的问题。
如何使用数组(如果可能)绘制内存使用量最少的图形?任何链接,参考学习都会很有用。
private void Pic1D_Click(object sender, RoutedEventArgs e)
{
Line myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
myLine.X1 = 20;
myLine.Y1 = 20;
for (int i=0; i<=8; i++)
{
myLine.X2 = i+20;
myLine.Y2 = i*i+20;
myLine.VerticalAlignment = VerticalAlignment.Center;
myLine.StrokeThickness = 2;
FunctionGrid.Children.Add(myLine);
myLine.X2 = myLine.X1;
myLine.Y2 = myLine.Y1;
}
}
我正在研究的另一个问题:是否可以通过在数组中使用二进制输入来绘制上图?主要是x值将以二进制表示,y将以二进制表示。有没有一个函数,我可以用它来做这个?我知道如何在二进制内容中转换它,尽管文件本身是一个原始文件。理想情况下,最后我想使用下面的读入文件在2 D中绘制上面的函数。
if (NewDialogx.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
xPath.Text = NewDialogx.FileName;
}
byte[] fileBytes = File.ReadAllBytes(@xPath.Text);
StringBuilder sb = new StringBuilder();
foreach (byte b in fileBytes)
{
count++;
if (count > 4096)
{
sb.Append(Convert.ToString(b, 2).PadLeft(1, '!'));
// GraphPlot[count-512,0,0] = Convert.ToString(b, 2).PadLeft(8, '0');
}
}
File.WriteAllText(@"C:\Users\raiti\Desktop\NEW1", sb.ToString());
以下是我尝试这样做的方法。我收到此异常处理错误:
System.ArgumentException:&#39;指定的Visual已经是另一个Visual的子项或CompositionTarget的根。&#39;
问题在于我不想将其创建为列表,因为这似乎非常不切实际(尽管请纠正我)如果我需要绘制大约10000多条数据线,并且可能占用一些空间。
我希望我已经足够具体了:)。
答案 0 :(得分:0)
我打算将其放在评论中,但有太多的方法,我有一些代码要显示。
在wpf应用程序中,我通常不会担心内存使用情况。这可能是在桌面上运行,即使是现在较弱的终端计算机也可以应对大量的图形。
您至少应该考虑使用图形软件。有一堆免费的可能性。我也不会完全忽略将wpf放在一边并将数据转储到磁盘上,以excel方式绘制图表。
如果这是一种学术练习,只有你使用最少的内存才能获胜,那么我必须尝试这些选项并查看他们使用了多少内存。 最有效的图形处理方式应该是各种绘图选项。你可以在图片中画线。尽管位图具有相当大的内存,但如果您有许多行,则可能会保存,因为位图大小不会上升,而其他方法会占用更多内存。 您可以在每个点之间使用绘制线绘制许多线条。 https://msdn.microsoft.com/en-us/library/system.windows.media.drawingcontext(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/ms606810(v=vs.110).aspx 下面的代码(我刚刚碰巧)在地图上绘制了一组线条,用作地图上的叠加层:
public static async Task<BitmapSource> GetGridImageAsync(FrameworkElement fe)
{
Matrix m = PresentationSource.FromVisual(fe)
.CompositionTarget.TransformToDevice;
double dpiFactor = 1 / m.M11;
return await Task.Run(() =>
{
Pen GreyPen = new Pen(Brushes.Gray, 1 * dpiFactor);
Pen GreyThickPen = new Pen(Brushes.Gray, 2 * dpiFactor);
GreyPen.Freeze();
int ix = 0;
int iy = 0;
int Width = 1155;
int Height = 805;
BitmapSource image = Visuals.CreateBitmap(
Width, Height, 96,
drawingContext =>
{
int count = 0;
while (ix <= Width)
{
if (count % 5 == 0)
{
drawingContext.DrawLine(
GreyThickPen, new Point(ix, 0), new Point(ix, Map.Height - 1));
}
else
{
drawingContext.DrawLine(
GreyPen, new Point(ix, 0), new Point(ix, Map.Height - 1));
}
ix += 35;
count++;
}
count = 0;
while (iy <= Width)
{
if (count % 5 == 0)
{
drawingContext.DrawLine(
GreyThickPen, new Point(0, iy), new Point(Map.Width -1, iy));
}
else
{
drawingContext.DrawLine(
GreyPen, new Point(0, iy), new Point(Map.Width - 1, iy));
}
iy += 35;
count++;
}
});
return image;
});
}
}
fe是传入的窗口,我使用缩放,因此线条清晰。它在我的机器上给出了.8的因子。
对于您的目的,这种低级方法可能并非真正必要,在这种情况下您可以使用折线(如Clemens建议的那样)。 使用wpf呈现大量内容的常用方法是使用itemscontrol并绑定itemssource。然后,将绑定的数据模板化为ui对象(在本例中为折线)。 折线采用点集合作为其Points属性。 如果您的数据被收集然后没有变化,您可以将其绑定在数据模板中,如:
<Polyline Points="{Binding Points}" Stroke="Red" StrokeThickness="2" />
其中points是一个公共属性,表示您对集合中每一行绑定到itemssource的某个对象的pointcollection。
如果您的线条应该是弯曲的,那么这要复杂得多。您可以使用路径进行贝塞尔曲线,但您可能需要根据您的点进行计算。 那时我会再次考虑使用专门构建的图形软件。
2)你的阵列。你可能想把它转换成某个地方的pointcollection。这可能是在转换器或视图模型中。 MVVM(和viewmodel)是wpf开发的事实标准模式。
3)你的错误。 当你尝试在两个地方使用一块ui时,你会得到它。 https://social.technet.microsoft.com/wiki/contents/articles/29964.wpf-tips-only-one-parent.aspx 有时它没有错误,但也没有给你预期的结果。 我想我需要查看更多代码来确定原因。