代码改变世界

Telerik的Silverlight控件学习系列之--用StyleSelector改变Grid样式

2011-04-19 13:06  Zork  阅读(1178)  评论(6编辑  收藏  举报

需求:

客户的希望数据发生改变后,用不同的颜色标记出来,同时希望在搜索的时候,将匹配的结果高亮显示。

 

分析:

       第一反应就是使用事件来处理这些功能。于是翻开文档,开始查看Grid的各种事件。无意中看到很多XXXStyle. 我想也许我们可以通过设置样式来改变显示效果吧。但是我们需要根据数据来呈现不同的外观,如果设置Style那么所有数据都是一样的颜色。这种方案好像不可行,但每个XXXStyle属性都会有一个XXXStyleSelector属性,这个是用来干啥?马上Google

 

 

StyleSelector介绍:

 

提供根据自定义逻辑应用样式的方法。用Reflector得到RowStyle的定义:


1 public class StyleSelector
2 {
3         public StyleSelector();
4         public virtual Style SelectStyle(object item, DependencyObject container);
5 }

 

具体实现

1. 用不同的颜色标记发生改变的数据行

 

a)       只需要重载SelectStyle, 然后根据数据返回不同的Style,就能让不同的数据呈现不同的UI

 

 1 public class FarmerItemStyleSelector : StyleSelector
 2 {
 3         public override Style SelectStyle(object item, DependencyObject container)
 4         { 
 5             var farmer = item as IFarmer;
 6             if (null == farmer)
 7                 return this.NormalStyle;
 8 
 9             if (farmer.IsChanged)
10                 return this.ChangedStyle;
11             return this.NormalStyle;
12         } 
13 
14         public Style NormalStyle { getset; }
15         public Style ChangedStyle { getset; }
16  }

 

b)       页面的Resources中定义StyleSelector,并设置好样式属性。

<Page.Resources>

<Landscape:FarmerItemStyleSelector x:Key="rowStyleSelector" >

            <Landscape:FarmerItemStyleSelector.ChangedStyle>

                <Style TargetType="telerik:GridViewRow">

                    <Setter Property="Background" Value="LightGreen" />

                </Style>

            </Landscape:FarmerItemStyleSelector.ChangedStyle>

    </Landscape:FarmerItemStyleSelector>

</Page.Resources>

 

c)       绑定GridRowStyleSelector属性:

<telerik:RadGridView Name="MainGrid" RowStyleSelector="{StaticResource rowStyleSelector}"  ItemsSource="{Binding ElementName=GridDataFilter, Path=FilteredSource}"

 

2. 高亮显示搜索匹配的结果

 

a)       首先定义好StyleSelector,将匹配成功的Cell用不同的样式标记。

 

 1 public class SearchedCellStyleSelector : StyleSelector
 2     {
 3         public override Style SelectStyle(object item, DependencyObject container)
 4         {
 5             if (string.IsNullOrEmpty(this.SearchText))
 6             {
 7                 return null;
 8             }
 9             var cell = container as GridViewCell;
10             if (cell == null)
11             {
12                 return null;
13             }
14 
15             if (cell.Value != null && cell.Value.ToString().IndexOf(this.SearchText) > -1)
16             {
17                 return HighlightedStyle;
18             }
19             return null;
20         }
21 
22         public Style HighlightedStyle { getset; }
23 
24         public string SearchText { getset; }
25     }

 

 

b)       页面的Resources中定义StyleSelector,并设置好样式属性

<Landscape:SearchedCellStyleSelector x:Key="cellStyleSelector">

            <Landscape:SearchedCellStyleSelector.HighlightedStyle>

                <Style TargetType="telerik:GridViewCell">

                    <Setter Property="Background" Value="Orange" />

                    <Setter Property="Foreground" Value="White" />

                </Style>

            </Landscape:SearchedCellStyleSelector.HighlightedStyle>

        </Landscape:SearchedCellStyleSelector>

 

c) 将定义好的StyleSelector绑定到GridColumn CellStyleSelector属性

<telerik:GridViewDataColumn UniqueName="CompanyColumn" Header="Company" CellStyleSelector="{StaticResource cellStyleSelector}" />

 

d)       将被搜索的文本传递给StyleSelector

this.QuickSearchTextBox.TextChanged += (s, e) =>

                {

                    var styleSelector = this.Resources["cellStyleSelector"] as SearchedCellStyleSelector;

                    styleSelector.SearchText = this.QuickSearchTextBox.Text;

                };

这一步本来是想通过绑定来完成,这样更优雅,不用在后台编写代码,更加符合MVVM的风格。但是绑定始终报错,未能解决这个问题。

 

3. 最终效果图: