SilverLight之路(十二)

上一节说了汇总行的模拟实现,效果还不错,但还是有些不完美,比如在表格的最右侧,垂直滚动条的地方就会出现宽度不同步,且两个表格区分太明显,如图

 SilverLight之路(十二)

想想实现的原理,就算我们设置了表格的宽度来同步,但垂直滚动条的问题还是解决不了,毕竟是在两个表格中实现的。

想想我们web中的实现,能不能在外面加一个”DIV”呢?以容器的滚动条来代替表格的滚动条,那样又会出现锁行销列的问题,不可行!不过这个方案给我们提供了另外一种思路,既然不能在外面加,那我在里面加不就可以了吗?利用sl强大的控件模板,我们在表格内部加上我们需要的内容,呵呵,这里,就是在gridQuotes表格中把我们的dgSummary表格塞进去。下图是我加完后的结果,可以与原始模板做对比。

 SilverLight之路(十二) 

在这里,我们可以清楚的看到datagrid的模板组成,发挥想像可以做出各种定制的效果,这就是控件模板的威力。回到我们的项目,我们注意到RowsPresenter这一个元素,它就是我们的主要表格区域,而下面的VerticalScrollbar就是指右侧的垂直滚动条,他们组合在一个grid中,并且位于同一行中,那我们就在原来RowsPresenter的位置入手(注意:上图是我已经加完dgSummary后的结果),加入一个Grid,上下两行,上面是RowsPresenter,下面是我们加入的dgSummary,然后想下我们的布局,与上一节中的反过来了,我们需要设置dgSummary的水平滚动条高度为0(设置不可见的话就不好用了),把gridQuotes的水平滚动条再重新设置出来。我们的ValueChange事件也要反过来,从dgSummary上去掉,加到gridQuotes上。利用上一节介绍的方法来进行相应的修改。

同步列宽:

  
    
private DataGrid FindSummaryDataGrid()
{
FrameworkElement fe
= this .gridQuotes as FrameworkElement;
DataGrid gd
= fe.GetVisualDescendants()
.OfType
< DataGrid > ()
.Where(s
=> s.Name == " dgSummary1 " )
.SingleOrDefault();
return gd;
}

void gridQuotes_LayoutUpdated( object sender, EventArgs e)
{
DataGrid gd
= FindSummaryDataGrid();
gd.Columns[
0 ].Width = new DataGridLength( this .gridQuotes.Columns[ 0 ].ActualWidth
+ this .gridQuotes.Columns[ 1 ].ActualWidth
+ this .gridQuotes.Columns[ 2 ].ActualWidth
+ this .gridQuotes.Columns[ 3 ].ActualWidth
+ this .gridQuotes.Columns[ 4 ].ActualWidth);

for ( int i = 1 ; i < gd.Columns.Count; i ++ )
{
gd.Columns[i].Width
= new DataGridLength( this .gridQuotes.Columns[i + 4 ].ActualWidth);
}
}

 

同步水平滚动条

  
    
private void HorizontalScrollbar_ValueChanged( object sender, System.Windows.RoutedPropertyChangedEventArgs < double > e)
{
DataGrid gd
= FindSummaryDataGrid();
gd.Scroll(DataGridScrollExtensions.ScrollMode.Horizontal, e.NewValue);
}

因为我们为了加入汇总表格,已经有了自定义的模板,所以可以直接在模板内部给水平滚动条注册事件。

最终,我们的效果如图

 SilverLight之路(十二)

至此,行情的主体列表已经基本完成了,接下来看一个简单的详情页,比如我们在行情列表里点击某只基金的名称时,可以在一个新的窗口中显示这只基金的详细信息,比如净值走势,这个页面我没有加太多的信息,主要是想实现一下走势图,如

 SilverLight之路(十二)

利用我们第五节中介绍的Chart控件,修改Series类型为LineSeries,然后绑定就行了,没有太大区别,代码如

  
    
LineSeries ls = this .chart1.Series[ 0 ] as LineSeries;
ls.DependentValueBinding
= new System.Windows.Data.Binding( " Dwjz " );
ls.IndependentValueBinding
= new System.Windows.Data.Binding( " FSRQ " );
ls.ItemsSource
= listJZ.Take( 100 );

不过这里有一个地方要注意,如果按barseries那样,先设置itemsource会报No suitable axis is available for plotting the dependent value.错误。

我们注意到,Chart里面的Series有一个AnimationSequence属性,它可以设置一些动画效果来展示数据,我本想在这里用它实现类似如动态画出曲线的效果,但失败了,网上找到解释说LineSeries不支持Animation,我它的Demo中,我只看到有柱图与饼图有动画效果,其它的都没有见到,不知道是不是只有柱图与饼图才有这个功能。

再介绍一个Tookit中的控件BusyIndicator,它用来显示一个等待窗口,类似之前我们用ChildWindow模拟的效果,但它可以有自己的区域,因为它是一个内容控件,我们可以把需要的控件放到其中,实现效果如

 SilverLight之路(十二)

显示全部按钮事件如下

  
    
void btnShowAll_Click( object sender, RoutedEventArgs e)
{
this .biWaiting.IsBusy = true ;
ThreadPool.QueueUserWorkItem((state)
=>
{
Dispatcher.BeginInvoke(()
=>
{
LineSeries ls
= this .chart1.Series[ 0 ] as LineSeries;
ls.ItemsSource
= listJZ;
this .biWaiting.IsBusy = false ;
});
});
}

关于BusyIndicator的详细用法,请参考Tookit Demo

你可能感兴趣的:(silverlight)