Is the DataContext accessible within a DataPointTemplate?
You're welcome, glad I could help out.
-Graham
I can't that you enough. I was doing this much less elegantly by passing all of the data through the ToolTip mapping and then refering to ToolTip.This and ToolTip.That in the ColumnChartTemplate.
kinda scary looking but its just all the boilerplate required to create attached properties and dependency properties.
The reason it needs the ToolTips is that they are currently the only information channel linking the Data point templates and the actual data points they are rendering.
Challenge accepted:
<Window x:Class="WpfApplication24.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" xmlns:igChart="http://infragistics.com/Chart" xmlns:local="clr-namespace:WpfApplication24"> <Window.Resources> <DataTemplate DataType="{x:Type igChart:ColumnChartTemplate}"> <Border Background="{Binding Path=Fill}" BorderBrush="{Binding Path=Stroke}" BorderThickness="{Binding Path=BorderThickness}" ToolTip="{Binding ToolTip}" local:DataManager.OwningChart="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type igChart:XamChart}}}" > <local:DataManager.ItemInfoFetcher> <local:ItemInfoFetcher x:Name="itemInfo" /> </local:DataManager.ItemInfoFetcher> <TextBlock Text="{Binding Item.Label, ElementName=itemInfo}" /> </Border> </DataTemplate> </Window.Resources> <Grid x:Name="testGrid"> <igChart:XamChart Name="testChart"> <igChart:XamChart.Series> <igChart:Series ChartType="Column" DataSource="{Binding}" DataMapping="Label=Label;Value=Value;ToolTip=Label" UseDataTemplate="True"/> </igChart:XamChart.Series> </igChart:XamChart> </Grid> </Window>
The code behind:
public class DataManager { public static readonly DependencyProperty ItemInfoFetcherProperty = DependencyProperty.RegisterAttached("ItemInfoFetcher", typeof(ItemInfoFetcher), typeof(DataManager), new PropertyMetadata(null, (o, e) => { AssignFetcher(o as FrameworkElement, e); })); private static void AssignFetcher(FrameworkElement frameworkElement, DependencyPropertyChangedEventArgs e) { if (e.OldValue != null) { ItemInfoFetcher oldFetcher = e.OldValue as ItemInfoFetcher; oldFetcher.Element = null; oldFetcher.ClearValue(ItemInfoFetcher.OwningChartProperty); } ItemInfoFetcher fetcher = e.NewValue as ItemInfoFetcher; fetcher.Element = frameworkElement; fetcher.SetBinding(ItemInfoFetcher.OwningChartProperty, new Binding() { Source = frameworkElement, Path = new PropertyPath(DataManager.OwningChartProperty) }); } public static ItemInfoFetcher GetItemInfoFetcher(DependencyObject target) { return (ItemInfoFetcher)target.GetValue(ItemInfoFetcherProperty); } public static void SetItemInfoFetcher(DependencyObject target, ItemInfoFetcher value) { target.SetValue(ItemInfoFetcherProperty, value); } public static readonly DependencyProperty ItemIndexProperty = DependencyProperty.RegisterAttached("ItemIndex", typeof(int), typeof(DataManager), new PropertyMetadata(-1)); public static int GetItemIndex(DependencyObject target) { return (int)target.GetValue(ItemIndexProperty); } public static void SetItemIndex(DependencyObject target, int value) { target.SetValue(ItemIndexProperty, value); } public static readonly DependencyProperty SeriesIndexProperty = DependencyProperty.RegisterAttached("SeriesIndex", typeof(int), typeof(DataManager), new PropertyMetadata(-1)); public static int GetSeriesIndex(DependencyObject target) { return (int)target.GetValue(SeriesIndexProperty); } public static void SetSeriesIndex(DependencyObject target, int value) { target.SetValue(SeriesIndexProperty, value); } public static readonly DependencyProperty OwningChartProperty = DependencyProperty.RegisterAttached("OwningChart", typeof(XamChart), typeof(DataManager), new PropertyMetadata(null)); public static XamChart GetOwningChart(DependencyObject target) { return (XamChart)target.GetValue(OwningChartProperty); } public static void SetOwningChart(DependencyObject target, XamChart value) { target.SetValue(OwningChartProperty, value); } } public class ItemInfoFetcher : FrameworkElement { public static readonly DependencyProperty OwningChartProperty = DependencyProperty.Register("OwningChart", typeof(XamChart), typeof(ItemInfoFetcher), new PropertyMetadata(null, (o, e) => { (o as ItemInfoFetcher).OnOwningChartChanged(e); })); private void OnOwningChartChanged(DependencyPropertyChangedEventArgs e) { UpdateItem(); } private void UpdateItem() { AssertTooltips(); if (OwningChart != null && Element != null) { FrameworkElement template = Element as FrameworkElement; if (template != null && template.ToolTip != null && template.ToolTip is DependencyObject) { int seriesIndex = DataManager.GetSeriesIndex( (DependencyObject)template.ToolTip); int dataPointIndex = DataManager.GetItemIndex( (DependencyObject)template.ToolTip); IList dataSource = OwningChart.Series[seriesIndex].DataSource as IList; if (dataSource != null) { Item = dataSource[dataPointIndex]; } } } } private void AssertTooltips() { if (OwningChart != null) { bool needsRefresh = false; for (int s = 0; s < OwningChart.Series.Count; s++) { Series series = OwningChart.Series[s]; for (int i = 0; i < series.DataPoints.Count; i++) { DataPoint dataPoint = series.DataPoints[i]; if (dataPoint.ToolTip != null) { if (!(dataPoint.ToolTip is DependencyObject)) { needsRefresh = true; dataPoint.ToolTip = new ContentPresenter() { Content = dataPoint.ToolTip }; } if (DataManager.GetItemIndex( (DependencyObject)dataPoint.ToolTip) < 0) { needsRefresh = true; DataManager.SetItemIndex( (DependencyObject)dataPoint.ToolTip, i); DataManager.SetSeriesIndex( (DependencyObject)dataPoint.ToolTip, s); } else { break; } } } } if (needsRefresh) { OwningChart.Refresh(); } } } public XamChart OwningChart { get { return (XamChart)GetValue(OwningChartProperty); } set { SetValue(OwningChartProperty, value); } } public FrameworkElement Element { get; set; } public static readonly DependencyProperty ItemProperty = DependencyProperty.Register("Item", typeof(object), typeof(ItemInfoFetcher), new PropertyMetadata(null)); public object Item { get { return (object)GetValue(ItemProperty); } set { SetValue(ItemProperty, value); } } }
Note this relies on there being at least some form of ToolTip set on the chart.If this is a problem you could probably style the ToolTips invisible.-Graham
Thanks, Graham. You wouldn't happen to have an attached property for THIS lying around anywhere, would you?