1

尝试从 Silverlight 工具包 Graph 创建可写位图时遇到问题。

使用 textBlock 时,一切正常,但尝试使用 Chart 后,生成的位图为空 :( 。

var data = new List<Point>(100);
for (int i = 0; i < 100; i++)
{
    data.Add(new Point(i, Math.Sin(i * Math.PI / 50)));
}

Chart chart_ = new Chart()
{
    Name = "Chart",
    Width = 512,
    Height = 512
};
LineSeries line = new LineSeries()
{
    Name = "Line",
    Title = "test",
    IndependentValuePath = "X",
    DependentValuePath = "Y",
    ItemsSource = data
};
chart_.Series.Add(line);

此代码在其中创建带有正弦曲线的图表。然后我试图从中创建位图。

LayoutRoot.Children.Add(chart_); // I tried to add chart_ to visual tree, It doesn't help 
//creates bitmap
ScaleTransform t = new ScaleTransform() { ScaleX = 1.0, ScaleY = 1.0 };
//bitmap = new WriteableBitmap(chart_, t); Tried it also with this way
bitmap = new WriteableBitmap(512, 512);
bitmap.Render(chart_, t);
texture = new Texture2D(GraphicsDeviceManager.Current.GraphicsDevice, bitmap.PixelWidth, bitmap.PixelHeight, false, SurfaceFormat.Color);
bitmap.CopyTo(texture);

所有这些代码都会创建空位图。但是当我使用 TextBlock 或 Ellipse 等一些原语时,一切正常。我确定,代码生成图表很好,因为在 Silverlight 控件中生成图表很好。

编辑: 我试图以这种方式创建位图,但它没有帮助。

chart_.InvalidateMeasure();
bitmap = new WriteableBitmap(512, 512);
bitmap.Render(chart_, null);
bitmap.Invalidate();

编辑 2: 我不希望图形出现在可视树中。我只需要生成它的图像,然后在我的应用程序的 XNA 部分中使用它。

4

3 回答 3

0

我相信,当您创建 WriteableBitmap 对象并调用 Render 方法时,Chart 尚未呈现。您可以通过将这些代码行移动到其他事件(如 Button_Click 等)来检查这一点。看看下面的代码,因为它正在创建 WriteableBitmap,然后将其作为源传递给图像控件......

XAML 代码.....

<UserControl x:Class="TryBitmap.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="35"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Height="25" Width="100" Content="Capture" Click="Button_Click"/>
    <Grid x:Name="grdGraphs" Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Image x:Name="img" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Grid>

代码背后....

public partial class MainPage : UserControl
{
    private Chart chart_;

    public MainPage()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        var data = new List<Point>(100);
        for (int i = 0; i < 100; i++)
        {
            data.Add(new Point(i, Math.Sin(i * Math.PI / 50)));
        }

        chart_ = new Chart()
        {
            Name = "Chart",
            Width = 512,
            Height = 512
        };
        LineSeries line = new LineSeries()
        {
            Name = "Line",
            Title = "test",
            IndependentValuePath = "X",
            DependentValuePath = "Y",
            ItemsSource = data
        };
        chart_.Series.Add(line);

        chart_.SetValue(Grid.ColumnProperty, 0);
        grdGraphs.Children.Add(chart_);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var bitmap = new WriteableBitmap((int)(chart_.RenderSize.Width), (int)(chart_.RenderSize.Height));
        bitmap.Render(chart_, new MatrixTransform());
        bitmap.Invalidate();

        img.Source = bitmap;
    }
}
于 2012-01-02T06:45:36.887 回答
0

只是一些小的更改,但我怀疑最大的更改是在使用 NuGet 添加 Charting 包之后手动添加对 System.Windows.Controls 的引用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.DataVisualization.Charting;
using System.Windows.Media.Imaging;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        Chart chart_;

        public MainPage()
        {
            InitializeComponent();

            var data = new List<Point>(100);
            for (int i = 0; i < 100; i++)
            {
                data.Add(new Point(i, Math.Sin(i * Math.PI / 50)));
            }

            chart_ = new Chart()
            {
                Name = "Chart",
                Width = 512,
                Height = 512
            };
            LineSeries line = new LineSeries()
            {
                Name = "Line",
                Title = "test",
                IndependentValuePath = "X",
                DependentValuePath = "Y",
                ItemsSource = data
            };
            chart_.Series.Add(line);
            LayoutRoot.Children.Add(chart_); // I tried to add chart_ to visual tree, It doesn't help  
        }

        private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {
            //creates bitmap 
            WriteableBitmap bitmap;
            ScaleTransform t = new ScaleTransform() { ScaleX = 1.0, ScaleY = 1.0 };
            //bitmap = new WriteableBitmap(chart_, t); Tried it also with this way 
            bitmap = new WriteableBitmap(512, 512);
            bitmap.Render(chart_, t);
            //texture = new Texture2D(GraphicsDeviceManager.Current.GraphicsDevice, bitmap.PixelWidth, bitmap.PixelHeight, false, SurfaceFormat.Color);
            //bitmap.CopyTo(texture); 
            image1.Source = bitmap;
        }
    }
}

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" 
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">

    <Grid x:Name="LayoutRoot" Background="White" Loaded="LayoutRoot_Loaded">
        <Image Height="150" HorizontalAlignment="Left" Margin="97,109,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="200" />
    </Grid>
</UserControl>

那应该让你去...

不要忘记删除所有尝试过的解决方法——我认为它们中的任何一个都不是必需的。我在您的示例中没有使用的唯一代码与纹理有关-我不知道该怎么做,无论如何这不是您遇到的问题...

大卫

于 2011-12-30T01:58:57.913 回答
0

恐怕这只会是一半的答案。我可以解决您当前的问题,但恐怕您最终会遇到另一个我无法解决的问题。

调用后创建位图Dispatcher.BeginInvoke应确保您的位图不是完全空白,即:

// do stuff with chart_ ...

Dispatcher.BeginInvoke(() =>
{
    bitmap = new WriteableBitmap(512, 512);
    bitmap.Render(chart_, null);
    bitmap.Invalidate();

    // At this point, the bitmap shouldn't be blank.
});

然而,这样的结果可能不太令人满意。我运行了您的代码,发现图表图像中缺少 LineSeries,尽管图表的其余部分在那里。即使在我将forDuration中的所有各种动画 设置为 0 并在图表上另外设置以下属性后,这仍然是正确的:ControlTemplateLineSeries

    chart_.AnimationSequence = AnimationSequence.Simultaneous;
    chart_.TransitionDuration = new TimeSpan(0);

我尝试将 WriteableBitmap 操作包装在对 的进一步调用中Dispatcher.BeginInvoke(),在这样做之后,数据点开始变得更加清晰。但是,我无法相信这样的方法是解决问题的正确方法。

于 2012-01-02T12:07:53.047 回答