在SetPower网站上,希望为考虑使用SetPower的用户提供一个工具,让他们能够估算使用SetPower能够节省多少能源。想要创建一个带有滑块的计算器,用户可以通过调整滑块来匹配他们的环境设置,例如计算机的功率、电脑数量、电价以及他们希望电脑休眠的时间比例。
可以在这里看到这个计算器。
当然,考虑过使用DOM脚本语言来开发这样的应用,但是动态图表的制作非常耗时(再加上职业生涯中大部分时间都在推动JavaScript的极限,所以几乎不喜欢编写JavaScript代码)。
也是MVVM模式的忠实粉丝。实际上,SetPower企业经理就是基于WPF MVVM模式的。最初,发现遵循这种模式很困难(尤其是面对复杂的用户界面),但是,像其他所有事情一样,随着经验的积累,会逐渐理解模式中的模式。
这是由Silverlight实例化的RootVisual。它完全是XAML,代码后端只包含以下内容:
public partial class CalculatorView : UserControl
{
public CalculatorView()
{
InitializeComponent();
txtWatts.TextChanged += new TextChangedEventHandler(txt_TextChanged);
txtComputerCount.TextChanged += new TextChangedEventHandler(txt_TextChanged);
}
void txt_TextChanged(object sender, TextChangedEventArgs e)
{
BindingExpression be = (sender as TextBox).GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
}
}
这段代码只是为了改变TextBox的绑定行为。在Silverlight中,TextBox的绑定更新是在TextBox失去焦点时触发的。但在情况下,希望它在用户按下键时就发生,这样他们就可以立即看到他们更改的影响。(最初没有这样做,但当让妻子测试时,她改变了瓦特数,然后从未离开过TextBox,然后想知道为什么更多的瓦特数没有增加她的节省。)
当最初学习MVVM时,挣扎于代码后端在视图中是可以接受的,只要代码只与视图有关。这里一个更干净的实现将是从一个派生的控件Textbox。
ViewModel在XAML中实例化并设置为数据上下文,它具有属性,这些属性为Wattage/SleepPercentage/Computer Count/Computer Type抛出INotifyPropertyChanged,并绑定到屏幕上的四个滑块。此外,一些装饰物,如笔记本电脑/台式机/电源台式机的图标,是绑定到视图模型属性的切换按钮。
还对一些属性进行了四舍五入(PercentSleep和EnergyRate),以避免在移动滑块时UI中出现长小数字符串。本应该将四舍五入作为一个IValueConverter来做,但只是直接在属性的setter中执行了这个操作。
这是一个非常简单的应用,可以在工作日完成,但有几件事情让放慢了速度。
想要一个更干净的饼图外观。通常,这种事情在Blend中是微不足道的,但在选择编辑模板->编辑副本后,留下了一个空的模板。最终从工具包源代码中提取了XAML。这样做之后,对图表本身和图例的格式进行了一些调整。
在各种博客上找到了几个如何做到这一点的例子,但它们都没有起作用。他们引用的StylePalette对象在2009年10月的库中并不存在。最终,发现StylePalette已被重命名为Palette,而Palette包含一个ResourceDictionaryCollection。
<charting:Chart x:Name="energyChart" Margin="0,8,7,0" HorizontalAlignment="Right" Width="276" Style="{StaticResource PieChartTemplate}" BorderBrush="{x:Null}">
<charting:PieSeries.Palette>
<datavis:ResourceDictionaryCollection>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="Control">
<Setter Property="Background" Value="{StaticResource PurpleHighlight}" />
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="Control">
<Setter Property="Background" Value="{StaticResource GreenHighlight}" />
</Style>
</ResourceDictionary>
</datavis:ResourceDictionaryCollection>
</charting:PieSeries.Palette>
<charting:PieSeries>
</charting:PieSeries>
</charting:Chart>