通过程序生成数据并将其绑定到Modern UI图表

本文关键字:绑定 Modern UI 图表 程序生成 数据 | 更新日期: 2023-09-27 18:22:07

我在将数据绑定到Modern UI Chart控件时遇到问题。

我并没有像创建XAML元素然后绑定到它那样使用它,我的目标是创建元素并在内存中渲染它,然后获取元素的图像。

我下面的代码是用于创建和添加内容的,图像的渲染效果很好。

    void generateGraphImg()
    {
        PieChart pc = new PieChart();
        ObservableCollection<TestClass>  Errors = new ObservableCollection<TestClass>();
        Errors.Add(new TestClass() { Category = "Globalization", Number = 75 });
        Errors.Add(new TestClass() { Category = "Features", Number = 2 });
        Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 });
        Errors.Add(new TestClass() { Category = "Correctness", Number = 83 });
        Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 });
        ChartSeries Charts = new ChartSeries();
        Charts.SeriesTitle = "Errors";
        Charts.DisplayMember = "Category";
        Charts.ValueMember = "Number";
        Charts.ItemsSource = Errors;
        pc.Series.Add(Charts);
        pc.ChartTitle = "Minimal Pie Chart";
        pc.ChartSubTitle = "Chart with fixed width and height";
        makeImgFromControl(pc, @"C:'Modern UI IMG'img.bmp");
    }
    void makeImgFromControl(UIElement control, string saveTo)
    {
        Viewbox viewbox = new Viewbox();
        viewbox.Child = control; //control to render
        viewbox.Measure(new System.Windows.Size(200, 200));
        viewbox.Arrange(new Rect(0, 0, 200, 200));
        viewbox.UpdateLayout(); //On PiePiece DrawGeometry() happens here
        RenderTargetBitmap render = new RenderTargetBitmap(500,500, 150, 150, PixelFormats.Pbgra32);
        render.Render(viewbox);
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(render));
        using (Stream s = File.Create(saveTo))
        {
            encoder.Save(s);
        }
    }

数据的绑定不呈现,但是,标题和副标题呈现精细的任何想法,为什么?

通过程序生成数据并将其绑定到Modern UI图表

解决方案隐藏在LayoutUpdated中,在破解了Modern UI Chart的代码一段时间后,我意识到了这一点。我需要等待才能获得img。

    void generateGraphImg()
    {
        PieChart pc = new PieChart();
        pc.LayoutUpdated += pc_LayoutUpdated;
        ObservableCollection<TestClass> Errors = new ObservableCollection<TestClass>();
        Errors.Add(new TestClass() { Category = "Globalization", Number = 75 });
        Errors.Add(new TestClass() { Category = "Features", Number = 2 });
        Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 });
        Errors.Add(new TestClass() { Category = "Correctness", Number = 83 });
        Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 });
        ChartSeries Charts = new ChartSeries();
        Charts.SeriesTitle = "Errors";
        Charts.DisplayMember = "Category";
        Charts.ValueMember = "Number";
        Charts.ItemsSource = Errors;
        pc.Series.Add(Charts);
        pc.ChartTitle = "Minimal Pie Chart";
        pc.ChartSubTitle = "Chart with fixed width and height";
        makeImgFromControl(pc, @"C:'Modern UI IMG'img.bmp");
    }
    void pc_LayoutUpdated(object sender, EventArgs e)
    {
        RenderTargetBitmap render = new RenderTargetBitmap(500,500, 150, 150, PixelFormats.Pbgra32);
        render.Render(viewbox);
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(render));
        using (Stream s = File.Create(@"C:'Modern UI IMG'img.bmp"))
        {
            encoder.Save(s);
        }
    }
    Viewbox viewbox;
    void makeImgFromControl(UIElement control, string saveTo)
    {
        viewbox = new Viewbox();
        viewbox.Child = control; //control to render
        viewbox.Measure(new System.Windows.Size(200, 200));
        viewbox.Arrange(new Rect(0, 0, 200, 200));
        viewbox.UpdateLayout();
    }

在添加ChartSeries之后,尝试分配ItemSource。因此更改顺序:

Charts.ItemsSource = Errors;
pc.Series.Add(Charts);

至:

pc.Series.Add(Charts);
Charts.ItemsSource = Errors;

我进行了测试,结果似乎有所不同。不完全确定原因,但图表对象可能只在收到集合更改通知时更新。


更新:从源代码来看,饼图似乎是由PiePiece控件组成的,它的构造函数中有:

public PiePiece()
{
    ...
    Loaded += PiePiece_Loaded;
}
void PiePiece_Loaded(object sender, RoutedEventArgs e)
{
      DrawGeometry();
}

所以它似乎只在实际CCD_ 3时绘制自己。