gpt4 book ai didi

wpf - 如何使用 WPF Toolkit 将多个图表与多个系列绑定(bind)?

转载 作者:行者123 更新时间:2023-12-03 10:37:41 24 4
gpt4 key购买 nike

我正在开发一个执行仪表板,该仪表板应该能够有任意数量的图表,每个图表都有任意数量的系列。我正在使用 WPF 工具包。

我遇到的第一个问题是将多个系列绑定(bind)到图表。我找到了Beat Kiener's excellent blogpost on binding multiple series to a chart在我将它放入项目控件之前效果很好,我必须这样做才能满足我的“任意数量的图表”要求。

在我看来,下面的代码应该可以工作,但事实并非如此。谁能解释为什么下面的代码不起作用,或者提供另一种使用 MVVM 的方法?

主窗口.xaml.cs

public partial class MainWindow : Window
{
public ChartData ChartData { get; set; }
public List<ChartData> ChartDataList { get; set; }

public MainWindow()
{
var dataSeries = new Dictionary<string, int>();
dataSeries.Add("Jan", 5);
dataSeries.Add("Feb", 7);
dataSeries.Add("Mar", 3);

ChartData = new ChartData();
ChartData.Title = "Chart Title";
ChartData.DataSeriesList = new List<Dictionary<string, int>>();
ChartData.DataSeriesList.Add(dataSeries);

ChartDataList = new List<ChartData>();
ChartDataList.Add(ChartData);

InitializeComponent();

this.DataContext = this;
}
}

public class ChartData
{
public string Title { get; set; }
public List<Dictionary<string, int>> DataSeriesList { get; set; }
}

主窗口.xaml
<UniformGrid
Rows="1">

<!-- These charts do not work -->
<ItemsControl
x:Name="itemsControl"
ItemsSource="{Binding ChartDataList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:MultiChart
Title="{Binding Title}"
SeriesSource="{Binding DataSeriesList}">
<local:MultiChart.SeriesTemplate>
<DataTemplate >
<chartingToolkit:ColumnSeries
Title="Series Title"
ItemsSource="{Binding}"
IndependentValueBinding="{Binding Key}"
DependentValueBinding="{Binding Value}"/>
</DataTemplate>
</local:MultiChart.SeriesTemplate>
</local:MultiChart>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- End of not working charts -->

<!-- This chart works -->
<local:MultiChart
Title="{Binding ChartData.Title}"
SeriesSource="{Binding ChartData.DataSeriesList}">
<local:MultiChart.SeriesTemplate>
<DataTemplate>
<chartingToolkit:ColumnSeries
Title="Series Title"
ItemsSource="{Binding}"
IndependentValueBinding="{Binding Key}"
DependentValueBinding="{Binding Value}" />
</DataTemplate>
</local:MultiChart.SeriesTemplate>
</local:MultiChart>
<!-- End of working chart -->

</UniformGrid>

MultiChart.cs
public class MultiChart : System.Windows.Controls.DataVisualization.Charting.Chart
{
#region SeriesSource (DependencyProperty)

public IEnumerable SeriesSource
{
get
{
return (IEnumerable)GetValue(SeriesSourceProperty);
}
set
{
SetValue(SeriesSourceProperty, value);
}
}

public static readonly DependencyProperty SeriesSourceProperty = DependencyProperty.Register(
name: "SeriesSource",
propertyType: typeof(IEnumerable),
ownerType: typeof(MultiChart),
typeMetadata: new PropertyMetadata(
defaultValue: default(IEnumerable),
propertyChangedCallback: new PropertyChangedCallback(OnSeriesSourceChanged)
)
);

private static void OnSeriesSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
IEnumerable oldValue = (IEnumerable)e.OldValue;
IEnumerable newValue = (IEnumerable)e.NewValue;
MultiChart source = (MultiChart)d;
source.OnSeriesSourceChanged(oldValue, newValue);
}

protected virtual void OnSeriesSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
this.Series.Clear();

if (newValue != null)
{
foreach (object item in newValue)
{
DataTemplate dataTemplate = null;

if (this.SeriesTemplate != null)
{
dataTemplate = this.SeriesTemplate;
}

// load data template content
if (dataTemplate != null)
{
Series series = dataTemplate.LoadContent() as Series;

if (series != null)
{
// set data context
series.DataContext = item;

this.Series.Add(series);
}
}
}
}
}

#endregion

#region SeriesTemplate (DependencyProperty)

public DataTemplate SeriesTemplate
{
get
{
return (DataTemplate)GetValue(SeriesTemplateProperty);
}
set
{
SetValue(SeriesTemplateProperty, value);
}
}

public static readonly DependencyProperty SeriesTemplateProperty = DependencyProperty.Register(
name: "SeriesTemplate",
propertyType: typeof(DataTemplate),
ownerType: typeof(MultiChart),
typeMetadata: new PropertyMetadata(default(DataTemplate))
);

#endregion
}

最佳答案

我终于弄明白了。

当你把 MultiChart ItemsControl 的内部SeriesSource属性设置在 SeriesTemplate 之前属性(property)。这不起作用,因为 OnSeriesSourceChanged方法需要知道SeriesTemplate是。我的解决方法是直接调用 OnSeriesSourceChanged方法每当 SeriesTemplate被改变。

private static void OnSeriesTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DataTemplate oldValue = (DataTemplate)e.OldValue;
DataTemplate newValue = (DataTemplate)e.NewValue;
MultiChart source = (MultiChart)d;
source.OnSeriesTemplateChanged(oldValue, newValue);
}

protected virtual void OnSeriesTemplateChanged(DataTemplate oldValue, DataTemplate newValue)
{
this.SeriesTemplate = newValue;
OnSeriesSourceChanged(SeriesSource, SeriesSource);
}

public static readonly DependencyProperty SeriesTemplateProperty = DependencyProperty.Register(
name: "SeriesTemplate",
propertyType: typeof(DataTemplate),
ownerType: typeof(MultiChart),
typeMetadata: new PropertyMetadata(
defaultValue: default(DataTemplate),
propertyChangedCallback: new PropertyChangedCallback(OnSeriesTemplateChanged)
)
);

关于wpf - 如何使用 WPF Toolkit 将多个图表与多个系列绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19327764/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com