none
DynamicDataDisplay问题之3,如何改变Legend,加一个框点击后所属的线条隐藏或是显示 RRS feed

答案

  • WPF中的解决方案,我们需要用到 EnumerableDataSource 或者其他种类的 DataSource, 然后设置好Mapping才可以。

        public MainWindow()
        {
          InitializeComponent();
    
          double[] x = new double[200];
          double[] y = new double[200];
          for (int i = 0; i < x.Length; i++)
            x[i] = 3.1415 * i / (x.Length - 1);
    
          for (int i = 0; i < 25; i++)
          {
            y = x.Select(v => Math.Sin(v + i / 10.0)).ToArray();
    
            var xDataSource = new EnumerableDataSource<double>(x);
            xDataSource.SetXMapping(X => X);
    
            var yDataSource = new EnumerableDataSource<double>(y);
            yDataSource.SetYMapping(Y => Y);
                   
            var lg = new LineGraph(new CompositeDataSource(xDataSource,yDataSource));
            lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, (byte)(i * 10), 0));
            lg.Description = new PenDescription(String.Format("Data series {0}", i + 1));
            lg.StrokeThickness = 2;
            plotter.Children.Add(lg);
          }
        }
    


    注意:Description 和加入到Plotter的方式也不同。

    因为WPF中,Legen没有设计成ItemsControl,而且D3中已经设计写死了 LineLegendItem 的ContentTemplate (详见:dynamicdatadisplay-31108\Stable\v0.3.1\src\DynamicDataDisplay\Charts\LineLegendItem.xaml)。所以我们需要来修改这个ContentTemplate:

        <DataTemplate x:Key="LineLegendItemContentTemplate" DataType="{x:Type d3:LineLegendItem}">
          <StackPanel Orientation="Horizontal">
            <CheckBox PreviewMouseLeftButtonDown="CheckBox_PreviewMouseLeftButtonDown" IsChecked="{Binding Path=ViewportElement.Visibility, Converter={StaticResource VisibilityToCheckedConverter}, Mode=TwoWay}"/>
            <Line Width="15" Height="15" X1="0" Y1="0" X2="15" Y2="15" Stroke="{Binding Pen.Brush}" 
    					    StrokeThickness="{Binding Pen.Thickness}" Margin="2,1,2,1"/>
            <TextBlock Margin="5,0,0,0" Text="{Binding Brief}"/>
          </StackPanel>
        </DataTemplate>
    


    而且,WPF中的Plotter会handle掉鼠标的事件,导致我们的CheckBox在Legen里面就接收不到鼠标事件了,所以我这里通过PreviewMouse事件,在CheckBox上优先处理鼠标单击:

        private void CheckBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
          (sender as CheckBox).IsChecked = !(sender as CheckBox).IsChecked;
          e.Handled = true;
        }
    

     

    完整的例子:https://skydrive.live.com/?cid=51b2fdd068799d15#cid=51B2FDD068799D15&id=51B2FDD068799D15%21900


    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    2012年1月12日 6:06
    版主