SilverLight之路(十)
这节我们看看“基金行情”表格中的细节,比如以不同颜色显示涨或跌;以横线显示没有值的数据等。
我们的表格是要体现基金的走势的,和股市一样,红色表示上涨,绿色表示下跌等,效果如
这个使用我们在“客户管理”中介绍的StringFormat就不行了,这里就要使用值转换器了。值转换器其实就是一个IValueConverter,它要求实现两个方法
Convert:表示数据由源向目标的转换
ConvertBack:表示数据由目标向源的转换(只在绑定为双向时才使用)
那么这里我要转换的目标值是颜色,我们的判断依据是数值,怎么做呢?看代码
public class IncomeColorConverter : IValueConverter
{
object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
decimal syl;
if (value == null) return new SolidColorBrush(Colors.White);
if (Decimal.TryParse(value.ToString(), out syl))
{
if(syl>0)
return new SolidColorBrush(Colors.Red);
else if (syl < 0)
return new SolidColorBrush(Colors.Green);
else
return new SolidColorBrush(Colors.White);
}
else
{
return new SolidColorBrush(Colors.White);
}
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
<TextBlock Text="{Binding 三个月收益}" Foreground="{Binding 三个月收益, Converter={StaticResource IncomeColorConverter}}"/>
这样就可以进行正常转换了,且效果也是我们想要的。(其实这里大可不必每次都去new,我是范懒了,呵呵)
同理,如果我们想在数据为空时以其它形式表现出来,比如两个小横线这样的要求,也可以使用转换器进行,方法是一样的,而且不会给排序带来问题,当然前提是你的数据源是正确的数据类型。但如果因为某种原因数值是以字符串来表示的,就像我这里这样,就会有问题了,那么解决办法也很简单,给列指定SortMemberPath属性,并且在数据源中增加一个数值型的属性成员,在访问处理器中进行数据转换就可以了,代码如
private string _一个月收益;
public string 一个月收益
{
set
{
_一个月收益 = value;
Decimal d;
if (Decimal.TryParse(value, out d))
一个月收益_Dec = d;
else
一个月收益_Dec = null;
}
get { return _一个月收益; }
}
public Decimal? 一个月收益_Dec { set; get; }
完整的前台代码如
<sdk:DataGridTemplateColumn Header="一个月收益率" IsReadOnly="True" SortMemberPath="一个月收益_Dec">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding 一个月收益, Converter={StaticResource IncomeTextConverter}}" Foreground="{Binding 一个月收益, Converter={StaticResource IncomeColorConverter}}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
这样就解决了颜色显示,格式化显示以及排序问题了。
这里提一下我在做WPF时遇到的一个问题,我用WPF做了一个类似sql server的查询分析器,表格列是自动生成的,即AutoGeneratingColumn,当某一列的内容超长时,如文章内容列,则默认情况下,datagrid会自适应大小,这样这一列的单元格就被撑的好大,不利于查看,行高可以设置,有直接属性,但列宽似乎不行,于是辗转反侧了好久,最后找到了一个办法,代码如
void gridResult_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Loaded += new RoutedEventHandler(Row_Loaded);
e.Row.Header = e.Row.GetIndex() + 1;
}
void Row_Loaded(object sender, RoutedEventArgs e)
{
foreach (DataGridColumn dc in this.gridResult.Columns)
{
if (dc.ActualWidth > 300)
dc.Width = 300;
}
}
不知道这个问题在sl中有木有,至少在我们“基金行情”与“客户管理”中没遇到。
这个界面数据量并不是很大,但当从服务器获取时也是有一定的延迟的。那做一个屏蔽好了,比如一个等待窗体,这里可以使用ChildWindow来实现。
实现代码,如加载时
cw.HasCloseButton = false;
cw.Height = 100;
cw.Width = 300;
cw.Content = "正在加载数据。。。";
cw.Show();
加载完成后再cw.Close();
默认情况下它会有一个背景遮罩层来覆盖全屏幕,当然这个遮罩也是可以设置的,如
更多细节可以参考