2011-07-28 42 views
4

一个月前我有一个项目,我在一个使用Windows Forms的应用程序中绘制了一个股票图表。我通过创建一个扩展到窗口大小的位图来实现这一点。这将允许我的图表调整窗口大小。在WPF中绘制图表C#设计问题

我现在正在使用WPF扩展项目。我一直在努力为这个项目设计我的设计,但我似乎无法理解做同一个图表的最佳方式。我看过画布,网格和其他一些控件。我以为我在画布的正确轨道上,但是当我调整窗口的大小时,我的绘画就会停留在同一个位置。我想我今晚的帖子的重点是想一些想法来帮助我为我的项目集思广益。

所有的意见和问题,赞赏。

感谢, 约瑟夫

回答

0

我假设你想绘制自己的图表而不是使用WPF图表。

画布通常不是一件好事情在WPF中使用,因为它修复了特定位置和大小的对象,完全如您所见(虽然我想您可以使用具有ScaleTransform的画布)。网格将采用其容器的大小,因此将网格放入窗口将使网格与窗口一起调整大小(除非您为网格指定了固定宽度和高度)。 StackPanel会堆叠一些东西并尝试获取其内容的最小大小,因此这可能不是您想要在此处使用的内容。

在面板内像Grid一样创建图表布局并不是很简单。如果您正在制作条形图,则可以在每个条形图的网格中创建一个列,指定一个百分比宽度,如星形;当你的网格随着窗口展开时,这些列会变大。您可以使用一个类似的技巧,将每个条设为网格,在网格中设置两列,并在最低列内设置第三级网格,然后使用百分比作为列高(例如,90%和10星为90%,10 %高度)。随着窗户变高,酒吧会长得更高。您可以在标签栏下方预留网格行,并将它们置于标签下方。

折线图比较复杂。您可能需要创建一个线段的几何图形绘制,然后使用绑定到窗口大小的ScaleTransform使其缩小和增大。

WPF有很多可能性,但您需要先学习一下,然后学习。像Adam Nathan的“Windows Presentation Foundation Unleashed”这样的书很快就会给你很多关于WPF布局的知识以及如何继续。

编辑:你也可以使用一个空的面板,并在您从当前窗口的大小来计算点使用其DrawingContext绘制线条,矩形,文本,椭圆等。

+0

我实际上已经能够使用窗口的ActualHeight/ActualWidth属性来玩。起初,我刚刚获得了NaN,但读到我必须等到“加载”完成。 – Teknos

+0

您也可以使用这些来进行直接绘图 - 更新了我的答案。 –

+0

我有两个窗口,一个用于控件,另一个用于图表。我已经完成了我的统计图的坐标网格,但是我直接将其绘制到网格中。我看到了一些这方面的缺陷,因为它没有按照窗口的比例调整大小......嗯,我将不得不仔细阅读你的答案并做更多的研究。感谢大家的帖子! – Teknos

0

有趣:我只是做同样的事情!

我已经开发了一个图表控件,有很多功能。现在我需要用其他功能来更新和扩展它。不过,我的交易甚至可以在单个图表上管理100k个点,但在普通PC上保持良好性能。通过调整窗口大小可以缩放图表,但不是最终放置的文本。还要考虑到我需要实时渲染至少0.5秒的数据。

所有已使用旧式位图创建解决的问题,然后将其作为普通图像放置在任何wpf控件上。有几个限制,因为没有像wpf那样的“活”对象,但与wpf基元相比,渲染性能非常巨大。

所以,除非你有最高100点的图表来管理,我强烈建议采用混合方法。无论如何,这是一项非常艰巨的任务!

干杯

1

(实现这一解决充其量这个相当老问题的一个子集,因为它只有一个图表类型...)

只是FWIW,创建一个Grid作为Ed suggests中的柱状图非常简单。这是一个快速和肮脏的版本:

Grid添加到您的Window的XAML。只是为了测试,这里是完全填充Window的一个。

<Grid> 
    <Grid 
     Name="myGrid" 
     HorizontalAlignment="Stretch" 
     VerticalAlignment="Stretch" 
     Width="auto" 
     Height="auto" 
     Margin="10,10,10,10" 
    /> 
</Grid> 

现在在您的项目中的某处插入这两个实用函数。这些提供了简单的单色列和无格式但居中的X轴标签文本。

我觉得唯一讨厌的kludge是_placeSingleColorColumn调用中的maxHeight

值得一提:我没有为y轴的标签在这个快速&脏版。

private void _placeSingleColorColumn(Grid grid, Color color, int height, int colNum, int maxHeight) 
{ 
    Brush brush = new SolidColorBrush(color); 

    Rectangle rect = new Rectangle(); 
    rect.Fill = brush; 
    Grid.SetColumn(rect, colNum); 
    Grid.SetRow(rect, maxHeight - height); 
    Grid.SetRowSpan(rect, height); 

    grid.Children.Add(rect); 
} 

private void _createLabels(Grid grid, string[] labels) 
{ 
    RowDefinition rowDefnLabels = new RowDefinition(); 
    grid.RowDefinitions.Add(rowDefnLabels); 

    for (int i = 0; i < labels.Length; i++) 
    { 
     TextBlock block = new TextBlock(); 
     block.Text = labels[i]; 
     block.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; 
     Grid.SetColumn(block, i); 
     Grid.SetRow(block, grid.RowDefinitions.Count); 
     grid.Children.Add(block); 
    } 
} 

这是真的了。下面是一些非常快速和肮脏的示例代码,用一些示例数据创建一个10乘10的网格。

public void createGrid10x10() 
{ 
    Random random = new Random(); 

    for (int i=0; i<10; i++) 
    { 
     ColumnDefinition colDef = new ColumnDefinition(); 
     myGrid.ColumnDefinitions.Add(colDef); 

     RowDefinition rowDef = new RowDefinition(); 
     myGrid.RowDefinitions.Add(rowDef); 

     Color color = i % 2 == 0 ? Colors.Red : Colors.Blue; 

     _placeSingleColorColumn(this.myGrid, color, random.Next(1,11), i, 10); 
    } 
    string[] aLabels = "Dogs,Cats,Birds,Snakes,Rabbits,Hamsters,Horses,Rats,Bats,Unicorns".Split(','); 
    _createLabels(this.myGrid, aLabels); 
} 

将一行添加到您的MainWindow构造函数中,然后完成,afaict。

public MainWindow() 
{ 
    InitializeComponent(); 
    this.createGrid10x10(); 
} 

现在你已经有了曲线图,一个酒吧会重新调整和调整窗口大小时留比例等

bar graph bar graph resized wider

添加更多标签(在顶栏值, y轴标签等)应该是非常简单明了的,如果你了解上述。只需投入另一列和/或行,创建您的TextBlock,并将它们放置在正确的位置。