[英]Adding ChartSeries programmatically (MVVM) in Modern UI (Metro) Charts
我一直在為我的項目尋找一個好看的圖表可視化解決方案,我終於找到了它( https://modernuicharts.codeplex.com )。 我也在那里的討論板上發布了這個問題,但我沒有回復......
我一直在玩一些圖表,我真的很喜歡它們。 非常光滑和美麗。 有一件事我需要更多信息,那就是我如何在運行時添加 ChartSeries。
編輯:我設法在運行時添加了欄,但有一些我似乎無法弄清楚的錯誤。 讓我們從一張圖片開始:
正如您在圖像中看到的,當我縮放窗口時,軸上的標題是正確的並且可以縮放。 這里的問題是酒吧。 條形似乎有固定的寬度,不想適應屏幕。 我這樣做的方式如下:
在 XAML 中,我像這樣放置控件:
<chart:StackedColumnChart ChartTitle="Total"
ChartSubTitle="(800)"
Series="{Binding Bars}">
</chart:StackedColumnChart>
在我后面的代碼中,我添加了這樣的 Bars:
using System;
using System.Collections.Generic;
using De.TorstenMandelkow.MetroChart;
using System.Collections.ObjectModel;
namespace AutoShop
{
class OccupationChartGroupViewModel
{
public OccupationChartGroupViewModel()
{
List<Tuple<string, int, double>> reqProdHoursPerWeek = DbServiceSegmentRequirement.GetProdSegReq();
List<Tuple<string, int, double>> reqPlanHoursPerWeek = DbServiceSegmentRequirement.GetPlanSegReq();
List<Tuple<string, int, double>> reqRepairHoursPerWeek = DbServiceSegmentRequirement.GetRepairSegReq();
List<Tuple<string, int, double>> reqHoursPerWeek = new List<Tuple<string, int, double>>();
reqHoursPerWeek.AddRange(reqProdHoursPerWeek);
reqHoursPerWeek.AddRange(reqPlanHoursPerWeek);
reqHoursPerWeek.AddRange(reqRepairHoursPerWeek);
reqHoursPerWeek.Sort();
switch (reqHoursPerWeek[0].Item2.ToString())
{
case "0":
if (reqHoursPerWeek[1].Item2.ToString() != "1")
reqHoursPerWeek.Add(new Tuple<string, int, double>(reqHoursPerWeek[0].Item1, 1, 0.0));
else
if (reqHoursPerWeek[1].Item1 != reqHoursPerWeek[0].Item1)
reqHoursPerWeek.Add(new Tuple<string, int, double>(reqHoursPerWeek[0].Item1, 1, 0.0));
break;
case "1":
reqHoursPerWeek.Add(new Tuple<string, int, double>(reqHoursPerWeek[0].Item1, 0, 0.0));
if (reqHoursPerWeek[1].Item2.ToString() != "2")
reqHoursPerWeek.Add(new Tuple<string, int, double>(reqHoursPerWeek[0].Item1, 2, 0.0));
else
if (reqHoursPerWeek[1].Item1 != reqHoursPerWeek[0].Item1)
reqHoursPerWeek.Add(new Tuple<string, int, double>(reqHoursPerWeek[0].Item1, 2, 0.0));
break;
case "2":
reqHoursPerWeek.Add(new Tuple<string, int, double>(reqHoursPerWeek[0].Item1, 0, 0.0));
reqHoursPerWeek.Add(new Tuple<string, int, double>(reqHoursPerWeek[0].Item1, 1, 0.0));
break;
default: break;
}
reqHoursPerWeek.Sort();
Bars = new ObservableCollection<De.TorstenMandelkow.MetroChart.ChartSeries>();
ObservableCollection<TestClass> blocks = new ObservableCollection<TestClass>();
foreach (Tuple<string, int, double> reqHours in reqHoursPerWeek)
{
string group = reqHours.Item2.ToString() == "2" ? "Order1" : reqHours.Item2.ToString() == "1" ? "Order2" : reqHours.Item2.ToString() == "0" ? "Order3" : "Unknown";
blocks.Add(new TestClass() { Category = group, Number = reqHours.Item3 });
if (reqHoursPerWeek.IndexOf(reqHours) + 1 < reqHoursPerWeek.Count)
{
if (reqHours.Item1 != reqHoursPerWeek[reqHoursPerWeek.IndexOf(reqHours) + 1].Item1)
{
ChartSeries chartSerie = new ChartSeries();
chartSerie.SeriesTitle = reqHours.Item1;
chartSerie.DisplayMember = "Category";
chartSerie.ValueMember = "Number";
chartSerie.ItemsSource = blocks;
Bars.Add(chartSerie);
blocks = new ObservableCollection<TestClass>();
}
}
else
{
ChartSeries chartSerie = new ChartSeries();
chartSerie.SeriesTitle = reqHours.Item1;
chartSerie.DisplayMember = "Category";
chartSerie.ValueMember = "Number";
chartSerie.ItemsSource = blocks;
Bars.Add(chartSerie);
}
}
}
public ObservableCollection<ChartSeries> Bars { get; private set; }
}
// class which represent a data point in the chart
public class TestClass
{
public string Category { get; set; }
public double Number { get; set; }
}
}
最后,我在 XAML 查看器中設計時遇到的錯誤是:
**NullReferenceException: Object reference not set to an instance of an object.**
**Stacktrace**
at De.TorstenMandelkow.MetroChart.ChartBase.UpdateDataContextOfSeries()
at De.TorstenMandelkow.MetroChart.ChartBase.InternalDataContextChanged()
at De.TorstenMandelkow.MetroChart.ChartBase.DataContextWatcher_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
at System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange)
at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
at System.Windows.Data.BindingExpression.Activate(Object item)
at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance)
at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
at MS.Internal.Data.DataBindEngine.Run(Object arg)
at MS.Internal.Data.DataBindEngine.OnLayoutUpdated(Object sender, EventArgs e)
at System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.UIElement.UpdateLayout()
**InnerException: None**
您正在使用 Series 而不是 SeriesSource 屬性(我嘗試使用 SeriesSource 但由於某種原因圖表顯示為空)。 無論如何,錯誤確實發生了,因為在 MVVM 調用 Series 綁定的 get 方法之前調用了上述方法,因此在 ChartBase.cs 的以下定義中將 Series 設為 null。 我希望你的解決方案中有這個項目,否則打開他們提供的代碼,更新代碼,編譯並引用生成的 dll。
private void UpdateDataContextOfSeries()
{
onApplyTemplateFinished = false;
//ADDED CODE STARTS
if(this.Series != null)
{
//ADDED CODE ENDS
foreach (var newItem in this.Series)
{
if (newItem is FrameworkElement)
{
(newItem as FrameworkElement).DataContext = this.DataContext;
}
}
onApplyTemplateFinished = true;
UpdateSeries();
//ADDED CODE STARTS
}
//ADDED CODE ENDS
}
只需要在運行循環和應用更新之前檢查系列是否為空。 一旦系列被獲取,這個方法也會被調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.