I have a viewmodel that has a list GraphConfig objects that I bind to an ItemsControl. I am trying to generate as much as I can from xaml but I have run into serveral areas that I am not able to use straight databinding. One of the first things I ran into is I was trying to bind the xaxis labelsetting visibility to a property on the GraphConfig object. The problem is that no matter what I put in there I always get the same error:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Infragistics.Controls.Charts.XamDataChart', AncestorLevel='1''. BindingExpression:Path=DataContext.IsLast; DataItem=null; target element is 'AxisLabelSettings' (HashCode=12116793); target property is 'Visibility' (type 'Visibility')
I thought the below code would work but it didn't. I also replaced this code with other bindings that do work in the same template and still get the same error.
<ig:AxisLabelSettings Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ig:XamDataChart}}, Path=DataContext.IsLast, Converter={StaticResource BooleanToVisibilityConverter}}" Location="OutsideBottom" />
Here is the template:
<ItemsControl ItemsSource="{Binding Graphs}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Vertical"></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <ig:XamDock x:Name="XamDataChartContainer1" Margin="0"> <ig:XamDataChart Margin="0" Height="200" CrosshairVisibility="Visible" CrosshairLineStyle="{StaticResource CrosshairLineStyle}" VerticalZoomable="False" VerticalZoombarVisibility="Collapsed" HorizontalZoomable="False" HorizontalZoombarVisibility="Collapsed" Background="Black" PlotAreaBorderBrush="Black" PlotAreaBackground="Black" BorderThickness="0" PlotAreaBorderThickness="0" Legend="{Binding ElementName=xmLegend}" > <behavior:ChartBehaviors.HoveredScatterItems> <behavior:HoveredScatterItemsBehavior /> </behavior:ChartBehaviors.HoveredScatterItems> <behavior:ChartBehaviors.HoveredCategoryItems> <behavior:HoveredCategoryItemsBehavior CategoryOffset="True"> <behavior:HoveredCategoryItemsBehavior.ItemComparer> <model:CustomDateTimeItemComparer /> </behavior:HoveredCategoryItemsBehavior.ItemComparer> </behavior:HoveredCategoryItemsBehavior> </behavior:ChartBehaviors.HoveredCategoryItems> <behavior:ChartBehaviors.FloatingTooltip> <behavior:FloatingTooltipBehavior TooltipTemplate="{StaticResource tooltipTemplate}" HoveredItems="{Binding Path=(behavior:ChartBehaviors.HoveredCategoryItems).HoveredItems}"/> </behavior:ChartBehaviors.FloatingTooltip> <ig:XamDataChart.Axes> <ig:NumericXAxis x:Name="dateAxis" Visibility="Visible" MinimumValue="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.MinDateTime.Ticks}" MaximumValue="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.MaxDateTime.Ticks}"> <ig:NumericXAxis.Label> <DataTemplate> <TextBlock Text="{Binding Path=Item, Converter={StaticResource TicksToDateTime}, ConverterParameter='HH:mm:ss'}" Foreground="White" /> </DataTemplate> </ig:NumericXAxis.Label> <ig:NumericXAxis.LabelSettings> <ig:AxisLabelSettings Visibility="Collapsed" Location="OutsideBottom" /> </ig:NumericXAxis.LabelSettings> </ig:NumericXAxis> </ig:XamDataChart.Axes> <ig:XamDataChart.Series> </ig:XamDataChart.Series> <ig:SyncManager.SyncSettings> <ig:SyncSettings SyncChannel="syncGroup1" SynchronizeHorizontally="True" SynchronizeVertically="False"/> </ig:SyncManager.SyncSettings> </ig:XamDataChart> <ig:Legend x:Name="xmLegend" ig:XamDock.Edge="InsideTop" ig:XamDock.HorizontalDockAlignment="Left" ig:XamDock.VerticalDockAlignment="Top" Style="{StaticResource LegendStyle}"> </ig:Legend> </ig:XamDock> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
Will I be able to add series in this method?
If I cannot dynamically create xamdatacharts. series and legend by databinding is there a way to replicate all the xaml in codebehind? for example how do I replicate this in code behind?
<ig:Legend x:Name="xmLegend"ig:XamDock.Edge="InsideTop"ig:XamDock.HorizontalDockAlignment="Left"ig:XamDock.VerticalDockAlignment="Top"Style="{StaticResource LegendStyle}"></ig:Legend>
And how do I add the above behaviors to the chart in the codebehind?
I have been able to replicate everything in codebehind now except for the behaviors. Anyone have an idea how to accomplish this in code behind? Here is my AddGraph function:
private void AddGraph(GraphConfig config) { var leftlegend = new Legend { Style = Resources["LegendStyle"] as Style }; var rightlegend = new Legend { Style = Resources["LegendStyle"] as Style };
var dock = new XamDock(); int sizepercent;
var graph = new XamDataChart { Margin = new Thickness(0), Height = (1080 - 200 - SelectionGrid.ActualHeight - 10) * (double.Parse(config.SizePercentage.TrimEnd( new char[] { '%', ' ' })) / 100), //This needs work to make it fluid. Had to assume 1080 for now and subtract off some for the header bar and some for the CrosshairVisibility = Visibility.Visible, CrosshairLineStyle = Resources["CrosshairLineStyle"] as Style, VerticalZoomable = false, VerticalZoombarVisibility = Visibility.Collapsed, HorizontalZoomable = false, HorizontalZoombarVisibility = Visibility.Collapsed, Background = new SolidColorBrush(Colors.Black), PlotAreaBorderBrush = new SolidColorBrush(Colors.Black), PlotAreaBackground = new SolidColorBrush(Colors.Black), BorderThickness = new Thickness(0), PlotAreaBorderThickness = new Thickness(0), Legend = leftlegend }; // Synchronize all the added graphs horizontally SyncManager.SetSyncSettings(graph, new SyncSettings { SyncChannel = "testsync", SynchronizeHorizontally = true, SynchronizeVertically = false });
// TODO: Figure out how to add the hover over items for popups to display the current values //var hoveredScatterItemBehavior = new HoveredScatterItemsBehavior(); //Interaction.GetBehaviors(graph).Add((Behavior)new LiveVue.Behaviors.HoveredScatterItemsBehavior()); var yaxis = new NumericYAxis { LabelSettings = new AxisLabelSettings { Visibility = Visibility.Visible, Location = AxisLabelsLocation.OutsideLeft, Foreground = new SolidColorBrush(Colors.White) }, //Label = null, Style = Resources["NumericYAxisStyle"] as Style, MinimumValue = 0, MaximumValue = 100 }; yaxis.IsInverted = yaxis.MinimumValue > yaxis.MaximumValue; yaxis.Name = String.Format("y_{0}", config.Name.RemoveSpecialCharacters());
var xaxis = new NumericXAxis { LabelSettings = new AxisLabelSettings { Visibility = config.IsLast ? Visibility.Visible : Visibility.Collapsed, // Only show the bottom xaxis labels Location = AxisLabelsLocation.OutsideBottom }, Name = "dateAxis", Label = Resources["NumericXAxisLabelTemplate"] as DataTemplate };
// these bindings ensure that all x axes have the same range xaxis.SetBinding(NumericAxisBase.MinimumValueProperty, new Binding("MinDateTime.Ticks")); xaxis.SetBinding(NumericAxisBase.MaximumValueProperty, new Binding("MaxDateTime.Ticks")); graph.Axes.Add(xaxis); graph.Axes.Add(yaxis);
dock.Children.Add(graph); dock.Children.Add(leftlegend); dock.Children.Add(rightlegend);
// Set the locations of the left and right legends XamDock.SetEdge(leftlegend, DockEdge.InsideTop); XamDock.SetHorizontalDockAlignment(leftlegend, HorizontalAlignment.Left); XamDock.SetEdge(rightlegend, DockEdge.InsideTop); XamDock.SetHorizontalDockAlignment(rightlegend, HorizontalAlignment.Right);
GraphStack.Children.Add(dock); }