添加 WPF 销售用户控件
现在看看如何创建 WPF 控件并将其添加到自定义 Outlook 窗体区域中。将 WPF 用户控件添加到自定义 Outlook 替换窗体区域中需要两个步骤。首先创建 WPF 用户控件,接着是将其添加到“替换”窗体区域中(它是稍早前创建的 RecentSales 窗体区域)。
要创建窗体,请将一个新的“WPF 用户控件库”项目添加到解决方案中。Visual Studio 将创建一个默认的控件并显示 XAML 编辑器。此时,可以设计 WPF 图表控件并添加事件处理程序。图 9 显示了 Visual Studio 2008 XAML 设计器中的 WPF 控件。
图 9 WPF 图表控件
由于已经添加了新的项目,因此将具有一些默认的 XAML 代码,但是设计器中只有空容器。因此,需要在此添加一些 XAML 代码来创建图表。为了对您有所帮助,图 10 显示了用于为窗体区域创建小型 WPF 销售图表的 XAML 代码。代码相当直接了当地创建了一个小控件,具有两列五行并将占位符文本放在图表上。此文本在运行时将被“销售”数据库中的数据更新。请注意,XAML 会根据在 XAML 代码头行的声明与 SalesChart 类相关联。
<UserControl x:Class="WpfChart.SalesChart"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid Name="Grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="190"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Name="Category1" Text="X1" Grid.Column="0"
Grid.Row="0" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Name="Category2" Text="X2" Grid.Column="0"
Grid.Row="1" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Name="Category3" Text="X3" Grid.Column="0"
Grid.Row="2" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Name="Category4" Text="X4" Grid.Column="0"
Grid.Row="3" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Name="Title" FontSize="14" FontWeight="Bold"
Text="Chart Title" Grid.Column="1" Grid.Row="4"
VerticalAlignment="Center" HorizontalAlignment="Right"/>
<Rectangle Name="Bar1" Fill="LightSteelBlue" RadiusX="5"
RadiusY="5" HorizontalAlignment="Left" Grid.Column="1"
Grid.Row="0" Width="170" Height="18"/>
<Rectangle Name="Bar2" Fill=" LightSteelBlue" RadiusX="5"
RadiusY="5" HorizontalAlignment="Left" Grid.Column="1"
Grid.Row="1" Width="170" Height="18"/>
<Rectangle Name="Bar3" Fill=" LightSteelBlue" RadiusX="5"
RadiusY="5" HorizontalAlignment="Left" Grid.Column="1"
Grid.Row="2" Width="170" Height="18"/>
<Rectangle Name="Bar4" Fill=" LightSteelBlue" RadiusX="5"
RadiusY="5" HorizontalAlignment="Left" Grid.Column="1"
Grid.Row="3" Width="170" Height="18"/>
<TextBlock Name="Label1" Text="$Y1" Grid.Column="1"
Grid.Row="0" VerticalAlignment="Center"
HorizontalAlignment="Right"/>
<TextBlock Name="Label2" Text="$Y2" Grid.Column="1"
Grid.Row="1" VerticalAlignment="Center"
HorizontalAlignment="Right"/>
<TextBlock Name="Label3" Text="$Y3" Grid.Column="1"
Grid.Row="2" VerticalAlignment="Center"
HorizontalAlignment="Right"/>
<TextBlock Name="Label4" Text="$Y4" Grid.Column="1"
Grid.Row="3" VerticalAlignment="Center"
HorizontalAlignment="Right"/>
</Grid>
</UserControl>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid Name="Grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="190"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Name="Category1" Text="X1" Grid.Column="0"
Grid.Row="0" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Name="Category2" Text="X2" Grid.Column="0"
Grid.Row="1" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Name="Category3" Text="X3" Grid.Column="0"
Grid.Row="2" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Name="Category4" Text="X4" Grid.Column="0"
Grid.Row="3" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Name="Title" FontSize="14" FontWeight="Bold"
Text="Chart Title" Grid.Column="1" Grid.Row="4"
VerticalAlignment="Center" HorizontalAlignment="Right"/>
<Rectangle Name="Bar1" Fill="LightSteelBlue" RadiusX="5"
RadiusY="5" HorizontalAlignment="Left" Grid.Column="1"
Grid.Row="0" Width="170" Height="18"/>
<Rectangle Name="Bar2" Fill=" LightSteelBlue" RadiusX="5"
RadiusY="5" HorizontalAlignment="Left" Grid.Column="1"
Grid.Row="1" Width="170" Height="18"/>
<Rectangle Name="Bar3" Fill=" LightSteelBlue" RadiusX="5"
RadiusY="5" HorizontalAlignment="Left" Grid.Column="1"
Grid.Row="2" Width="170" Height="18"/>
<Rectangle Name="Bar4" Fill=" LightSteelBlue" RadiusX="5"
RadiusY="5" HorizontalAlignment="Left" Grid.Column="1"
Grid.Row="3" Width="170" Height="18"/>
<TextBlock Name="Label1" Text="$Y1" Grid.Column="1"
Grid.Row="0" VerticalAlignment="Center"
HorizontalAlignment="Right"/>
<TextBlock Name="Label2" Text="$Y2" Grid.Column="1"
Grid.Row="1" VerticalAlignment="Center"
HorizontalAlignment="Right"/>
<TextBlock Name="Label3" Text="$Y3" Grid.Column="1"
Grid.Row="2" VerticalAlignment="Center"
HorizontalAlignment="Right"/>
<TextBlock Name="Label4" Text="$Y4" Grid.Column="1"
Grid.Row="3" VerticalAlignment="Center"
HorizontalAlignment="Right"/>
</Grid>
</UserControl>
创建 WPF 图表后,过程的最后一步是确保创建方法,以便随着数据的更改而更新图表。在 SalesChart 类中,UpdateWPFChart 方法主要以 chart title(公司名称)和代表销售数据的两个字符串数组作为参数,根据此数据调整图表并更新图表的文本和条形指示器,如图 11 所示。
public void UpdateWPFChart(string chartTitle,
string[] xVals, double[] yVals)
{
double maxY = 0;
foreach (double y in yVals)
{
if (y > maxY)
maxY = y;
}
try
{
for (int i = 0; i < 4; i++)
{
if ((i >= xVals.Length) || (i >= yVals.Length))
break;
else
{
TextBlock xText = (TextBlock)(FindName(
String.Format("Category{0}", i + 1)));
if (xText != null)
xText.Text = xVals[i];
TextBlock yText = (TextBlock)(FindName(
String.Format("Label{0}", i + 1)));
if (yText != null)
yText.Text = yVals[i].ToString();
Rectangle bar = (Rectangle)(FindName(
String.Format("Bar{0}", i + 1)));
bar.Width = (yVals[i] / maxY) *
Grid1.ColumnDefinitions[1].Width.Value;
}
}
Title.Text = chartTitle;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SalesChart", MessageBoxButton.OK);
}
}
string[] xVals, double[] yVals)
{
double maxY = 0;
foreach (double y in yVals)
{
if (y > maxY)
maxY = y;
}
try
{
for (int i = 0; i < 4; i++)
{
if ((i >= xVals.Length) || (i >= yVals.Length))
break;
else
{
TextBlock xText = (TextBlock)(FindName(
String.Format("Category{0}", i + 1)));
if (xText != null)
xText.Text = xVals[i];
TextBlock yText = (TextBlock)(FindName(
String.Format("Label{0}", i + 1)));
if (yText != null)
yText.Text = yVals[i].ToString();
Rectangle bar = (Rectangle)(FindName(
String.Format("Bar{0}", i + 1)));
bar.Width = (yVals[i] / maxY) *
Grid1.ColumnDefinitions[1].Width.Value;
}
}
Title.Text = chartTitle;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SalesChart", MessageBoxButton.OK);
}
}
此时即完成了窗体区域的所有控件,因此现在可以返回到 Outlook 替换窗体区域设计器,添加刚刚创建的控件并将它们连接到自定义窗体区域。