我最近做了类似的事情。虽然 SeriesMappings 本身和绑定是在代码隐藏中创建的,但我的 SeriesMappings 的 ItemSources 已绑定。
我的视图模型在其数据全部加载后触发了一个事件。视图处理了事件并将新的 SeriesMapping 对象添加到图表中。下面是一些用于创建 SeriesMapping 对象的代码。
void AddBarSeriesMapping(string itemsSourceBindingPath, string legendLabel, string itemFieldName = null)
{
this.AddSeriesMapping(itemsSourceBindingPath, legendLabel, CreateBarSeriesDefinition(), itemFieldName);
}
void AddLineSeriesMapping(string itemsSourceBindingPath, string legendLabel, string itemFieldName = null)
{
this.AddSeriesMapping(itemsSourceBindingPath, legendLabel, CreateLineSeriesDefinition(), itemFieldName);
}
void AddSeriesMapping(string itemsSourceBindingPath, string legendLabel, ISeriesDefinition seriesDefinition, string itemFieldName)
{
//
// Set label and type (bar/line/etc).
//
SeriesMapping seriesMapping = new SeriesMapping
{
ChartArea = this.Chart.DefaultView.ChartArea,
LegendLabel = legendLabel,
SeriesDefinition = seriesDefinition
};
//
// Bind to items source.
//
BindingOperations.SetBinding(seriesMapping, SeriesMapping.ItemsSourceProperty, new Binding(itemsSourceBindingPath));
//
// Map items to the Y value, and set field name if the items source is not a list of numeric values.
//
var itemMapping = new ItemMapping { DataPointMember = DataPointMember.YValue };
if (itemFieldName != null)
{
itemMapping.FieldName = itemFieldName;
}
seriesMapping.ItemMappings.Add(itemMapping);
this.Chart.SeriesMappings.Add(seriesMapping);
}
private static ISeriesDefinition CreateBarSeriesDefinition()
{
return new BarSeriesDefinition
{
ShowItemLabels = false,
ShowItemToolTips = true,
ItemToolTipFormat = "#Y",
InteractivitySettings = DefaultInteractivitySettings
};
}
private static ISeriesDefinition CreateLineSeriesDefinition()
{
return new LineSeriesDefinition
{
ShowItemLabels = false,
ShowItemToolTips = true,
ItemToolTipFormat = "#Y",
InteractivitySettings = DefaultInteractivitySettings
};
}
private static InteractivitySettings DefaultInteractivitySettings;
static ChartSummaryView()
{
DefaultInteractivitySettings = new InteractivitySettings
{
HoverScope = InteractivityScope.Series,
SelectionScope = InteractivityScope.Item
};
}
更新:
为了让视图模型将数据和映射信息传递给视图,也许您可以这样做。
public class SeriesMappingInfo
{
public int DataSourceIndex { get; set; } // Index in ViewModel.DataSources
public string LegendLabel { get; set; }
// Other properties to tell the view how to create the mapping...
}
public class ViewModel
{
public event EventHandler DataLoaded;
public double?[][] DataSources { get; private set; }
public SeriesMappingInfo[] Mappings { get; private set; }
private void OnDataRetrievedFromServer(ReportData data)
{
// TODO: Translate data into something SeriesMappings can bind to, and set DataSources property.
// TODO: Assemble info for creating SeriesMappings, and set Mappings property.
// Tell the view everything is ready.
if (this.DataLoaded != null)
{
this.DataLoaded(this, EventArgs.Empty);
}
}
}
public class View : UserControl
{
public View()
{
this.DataContextChanged += new DependencyPropertyChangedEventHandler(View_DataContextChanged);
// InitializeComponent, etc.
}
private void View_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var viewModel = e.NewValue as ViewModel;
if (viewModel != null)
{
this.CreateSeriesMappings(viewModel.Mappings);
viewModel.DataLoaded += new EventHandler(ViewModel_DataLoaded);
}
}
private void ViewModel_DataLoaded(object sender, EventArgs e)
{
var viewModel = sender as ViewModel;
if (viewModel != null)
{
this.CreateSeriesMappings(viewModel.Mappings);
}
}
private void CreateSeriesMappings(SeriesMappingInfo[] seriesMappingInfo)
{
var chartSeriesMappings = seriesMappingInfo.Select(m =>
{
// TODO: Create mapping. The binding would look something like this:
var seriesMapping = new SeriesMapping();
BindingOperations.SetBinding(seriesMapping, SeriesMapping.ItemsSourceProperty, new Binding(String.Format("DataSources[{0}]", m.DataSourceIndex)));
return seriesMapping;
});
// TODO: Give these mappings to the chart control.
}
}