Hi,
How could I highlight a particular column on mouse hover?
David
This is not easy, currently, since we don't allow the customization of the shapes used in the column chart.I would recommend making a feature request for this capability.You still can get the effect you want through some fancy manipulation of the Rectangle's implicit style though.Xaml:
<Grid x:Name="LayoutRoot" Background="White"> <igChart:XamDataChart x:Name="theChart"> <igChart:XamDataChart.Axes> <igChart:NumericYAxis x:Name="yAxis" /> <igChart:CategoryXAxis x:Name="xAxis" ItemsSource="{StaticResource data}" Label="{}{Label}"/> </igChart:XamDataChart.Axes> <igChart:XamDataChart.Series> <igChart:ColumnSeries x:Name="series" ItemsSource="{StaticResource data}" XAxis="{Binding ElementName=xAxis}" YAxis="{Binding ElementName=yAxis}" ValueMemberPath="Value" > <igChart:ColumnSeries.Resources> <Style TargetType="Rectangle"> <Setter Property="local:StyleBinder.StyleBinderHelper"> <Setter.Value> <local:StyleBinderHelper> <local:StyleBinderHelper.Template> <DataTemplate> <local:RectangleMouseOver MouseFill="Yellow" Rectangle="{Binding Owner}" /> </DataTemplate> </local:StyleBinderHelper.Template> </local:StyleBinderHelper> </Setter.Value> </Setter> </Style> </igChart:ColumnSeries.Resources> </igChart:ColumnSeries> </igChart:XamDataChart.Series> </igChart:XamDataChart> </Grid>
And code behind:
public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } } public class TestData : ObservableCollection<TestDataItem> { public TestData() { Add(new TestDataItem() { Label = "A", Value = 1 }); Add(new TestDataItem() { Label = "B", Value = 2 }); Add(new TestDataItem() { Label = "C", Value = 3 }); Add(new TestDataItem() { Label = "D", Value = 4 }); } } public class TestDataItem { public string Label { get; set; } public double Value { get; set; } } public static class StyleBinder { public static readonly DependencyProperty StyleBinderHelperProperty = DependencyProperty.RegisterAttached( "StyleBinderHelper", typeof(StyleBinderHelper), typeof(StyleBinder), new PropertyMetadata(null, (o, e) => StyleBinderHelperChanged(o, e))); private static void StyleBinderHelperChanged( DependencyObject o, DependencyPropertyChangedEventArgs e) { FrameworkElement ele = o as FrameworkElement; if (ele == null) { return; } BindingExpression be = ele.GetBindingExpression ( StyleBinder.StyleBinderContextProperty); if (be == null) { ele.SetBinding(StyleBinderContextProperty, new Binding()); } if (e.NewValue != null) { ((StyleBinderHelper)e.NewValue).PushContent(ele); } } public static void SetStyleBinderHelper( DependencyObject target, StyleBinderHelper value) { target.SetValue(StyleBinderHelperProperty, value); } public static StyleBinderHelper GetStyleBinderHelper( DependencyObject target) { return (StyleBinderHelper)target.GetValue(StyleBinderHelperProperty); } public static readonly DependencyProperty StyleBinderContentProperty = DependencyProperty.RegisterAttached( "StyleBinderContent", typeof(FrameworkElement), typeof(StyleBinder), new PropertyMetadata(null, (o, e) => StyleBinderContentChanged(o, e))); private static void StyleBinderContentChanged( DependencyObject o, DependencyPropertyChangedEventArgs e) { } public static void SetStyleBinderContent( DependencyObject target, FrameworkElement value) { target.SetValue(StyleBinderContentProperty, value); } public static FrameworkElement GetStyleBinderContent( DependencyObject target) { return (FrameworkElement)target.GetValue(StyleBinderContentProperty); } public static readonly DependencyProperty StyleBinderContextProperty = DependencyProperty.RegisterAttached( "StyleBinderContext", typeof(object), typeof(StyleBinder), new PropertyMetadata(null, (o, e) => StyleBinderContextChanged(o, e))); private static void StyleBinderContextChanged( DependencyObject o, DependencyPropertyChangedEventArgs e) { FrameworkElement content = StyleBinder.GetStyleBinderContent(o); if (content != null) { content.DataContext = new HelperContext() { OuterContext = e.NewValue, Owner = o as FrameworkElement }; } } public static void SetStyleBinderContext( DependencyObject target, object value) { target.SetValue(StyleBinderContextProperty, value); } public static object GetStyleBinderContext( DependencyObject target) { return target.GetValue(StyleBinderContextProperty); } } public class StyleBinderHelper : FrameworkElement { internal void PushContent(FrameworkElement ele) { if (Template == null) { return; } FrameworkElement content = Template.LoadContent() as FrameworkElement; if (content == null) { return; } content.DataContext = new HelperContext() { OuterContext = StyleBinder.GetStyleBinderContext(ele), Owner = ele }; StyleBinder.SetStyleBinderContent(ele, content); } public DataTemplate Template { get; set; } } public class HelperContext : INotifyPropertyChanged { private object _outerContext; public object OuterContext { get { return _outerContext; } set { _outerContext = value; RaisePropertyChanged("OuterContext"); } } private FrameworkElement _owner; public FrameworkElement Owner { get { return _owner; } set { _owner = value; RaisePropertyChanged("Owner"); } } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } public class RectangleMouseOver : FrameworkElement { public static readonly DependencyProperty MouseFillProperty = DependencyProperty.Register( "MouseFill", typeof(Brush), typeof(RectangleMouseOver), new PropertyMetadata(null, (o, e) => (o as RectangleMouseOver) .MouseFillChanged(e))); public Brush MouseFill { get { return (Brush)GetValue(MouseFillProperty); } set { SetValue(MouseFillProperty, value); } } public static readonly DependencyProperty RectangleProperty = DependencyProperty.Register( "Rectangle", typeof(Rectangle), typeof(RectangleMouseOver), new PropertyMetadata(null, (o, e) => (o as RectangleMouseOver) .RectangleChanged(e))); private void RectangleChanged(DependencyPropertyChangedEventArgs e) { if (e.OldValue != null) { (e.OldValue as Rectangle).MouseEnter -= RectangleMouseOver_MouseEnter; (e.OldValue as Rectangle).MouseLeave -= RectangleMouseOver_MouseLeave; } if (e.NewValue != null) { (e.NewValue as Rectangle).MouseEnter += RectangleMouseOver_MouseEnter; (e.NewValue as Rectangle).MouseLeave += RectangleMouseOver_MouseLeave; } } BindingExpression oldBinding = null; Brush oldBrush = null; void RectangleMouseOver_MouseLeave(object sender, MouseEventArgs e) { if (Rectangle == null) { return; } if (oldBinding != null) { Rectangle.ClearValue(Shape.FillProperty); Rectangle.SetBinding(Shape.FillProperty, oldBinding.ParentBinding); } else if (oldBrush != null) { Rectangle.Fill = oldBrush; } } void RectangleMouseOver_MouseEnter(object sender, MouseEventArgs e) { if (Rectangle == null) { return; } oldBinding = Rectangle.GetBindingExpression (Shape.FillProperty); oldBrush = Rectangle.Fill; Rectangle.Fill = MouseFill; } public Rectangle Rectangle { get { return (Rectangle)GetValue(RectangleProperty); } set { SetValue(RectangleProperty, value); } } private void MouseFillChanged(DependencyPropertyChangedEventArgs e) { } }
Hope this helps!-Graham
Here is a more concise way of doing it, if you don't mind using some event handlers in your code behind:
<Grid x:Name="LayoutRoot" Background="White"> <igChart:XamDataChart x:Name="theChart" SeriesMouseEnter="theChart_SeriesMouseEnter" SeriesMouseLeave="theChart_SeriesMouseLeave"> <igChart:XamDataChart.Axes> <igChart:NumericYAxis x:Name="yAxis" /> <igChart:CategoryXAxis x:Name="xAxis" ItemsSource="{StaticResource data}" Label="{}{Label}"/> </igChart:XamDataChart.Axes> <igChart:XamDataChart.Series> <igChart:ColumnSeries x:Name="series" ItemsSource="{StaticResource data}" XAxis="{Binding ElementName=xAxis}" YAxis="{Binding ElementName=yAxis}" ValueMemberPath="Value" > </igChart:ColumnSeries> </igChart:XamDataChart.Series> </igChart:XamDataChart> </Grid>
public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private BindingExpression _oldBinding; private Brush _oldBrush = null; private Shape _oldShape = null; private void theChart_SeriesMouseEnter( object sender, Infragistics.Controls.Charts.ChartMouseEventArgs e) { Shape s = e.OriginalSource as Shape; if (s == null) { return; } _oldBinding = s.GetBindingExpression (Shape.FillProperty); _oldBrush = s.Fill; _oldShape = s; s.Fill = new SolidColorBrush(Colors.Yellow); } private void theChart_SeriesMouseLeave( object sender, Infragistics.Controls.Charts.ChartMouseEventArgs e) { if (_oldShape == null) { return; } if (_oldBinding != null) { _oldShape.ClearValue(Shape.FillProperty); _oldShape.SetBinding(Shape.FillProperty, _oldBinding.ParentBinding); } else if (_oldBrush != null) { _oldShape.Fill = _oldBrush; } } } public class TestData : ObservableCollection<TestDataItem> { public TestData() { Add(new TestDataItem() { Label = "A", Value = 1 }); Add(new TestDataItem() { Label = "B", Value = 2 }); Add(new TestDataItem() { Label = "C", Value = 3 }); Add(new TestDataItem() { Label = "D", Value = 4 }); } } public class TestDataItem { public string Label { get; set; } public double Value { get; set; } }