65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Silverlight 中做一些有用的事情 - 第 1 部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (7投票s)

2012 年 7 月 29 日

CPOL

7分钟阅读

viewsIcon

22293

downloadIcon

263

这是关于您可能希望包含在 Silverlight 应用程序中的一些有用功能的一系列文章的第一个部分。

引言

在这个网站上,我们经常会看到成员提出非常基础的问题。因此,我决定发布一些关于如何在 Silverlight 应用程序中执行一些有用任务的文章(我们将有一系列文章)。

在这篇文章中,我们将学习模板和本地化。所有这些主题都将提供两个版本:XAML 和代码隐藏。您可以下载一个解决方案中 5 个 Silverlight 项目的源代码,并附有解释(注释)。在本文的末尾,我嵌入了演示,向您展示每个主题的工作方式。

主题

在这篇文章中,我们将学习以下要点:

  1. 通过 XAML 在控件内部和通过资源实现模板。
  2. 通过代码隐藏在控件内部和通过资源实现模板。
  3. 通过 XAML 和代码隐藏实现本地化。

那么,让我们开始吧。

项目结构

我们需要一个解决方案中的 5 个项目。在这种情况下,解决方案将命名为 UsefulThingPart1。项目结构如下:

通用步骤

创建 Silverlight 项目后,我们必须启用浏览器外功能。为此,我们必须右键单击创建的项目,然后搜索我将在以下截图中展示的选项。

在每个按钮上,您都会看到以下事件处理程序:

private void Button_Click(object sender, RoutedEventArgs e)
{
     MessageBox.Show("You Clicked Me!");
}  

每次单击按钮时,我们都会看到以下 MessageBox

通过 XAML 在 Button 和 ComboBox 中实现模板

在我们的解决方案 (UsefulThingPart1.sln) 中,我们必须添加一个名为 TemplatesXAML 的新项目,我们在其中添加两个控件。首先,从工具箱将一个 Button 拖放到您的 MainPage.xaml 页面中。生成的 XAML 代码如下:

<Button Content="Click Me!" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click"/>    

如果我们运行项目 (F5),我们将看到一个文本为“Click Me!”的 Button,如果我们单击该按钮,我们将看到 MessageBox

现在是时候为这个按钮创建模板了。我们的想法是添加一个图标,然后是左对齐和居中的文本。在这种情况下,我们必须在按钮内添加以下标签。此外,您必须删除按钮声明中的 Content 属性。

XAML 代码如下:

<Button HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click" Margin="0 30 0 0">
            <Button.Content>
                <StackPanel Orientation="Horizontal">
                    <Image Source="Images/Click.png" Width="32" Height="32"
                           Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Left" />
                    <TextBlock Text="Click Me!" HorizontalAlignment="Left" VerticalAlignment="Center"  />
                </StackPanel>
            </Button.Content>
</Button> 

再次运行项目 (F5),我们将看到带有模板和不带模板的两个按钮。

现在我们尝试添加一个 ComboBox,我们在其中显示一些选项,只需编写以下 XAML 代码:

<ComboBox HorizontalAlignment="Left" Margin="0,80,0,0" VerticalAlignment="Top" >
      <ComboBoxItem Content="Item 1" />
      <ComboBoxItem Content="Item 2" />
      <ComboBoxItem Content="Item 3" />
      <ComboBoxItem Content="Item 4" />
      <ComboBoxItem Content="Item 5" />
</ComboBox> 

添加 ComboBox 后,我们可以在每个 ComboBoxItem 中添加模板。

<ComboBox HorizontalAlignment="Left" Margin="-1,110,0,0" VerticalAlignment="Top" >
            <ComboBoxItem >
                <ComboBoxItem.Content>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Images/ComboItem.png" />
                        <TextBlock Text="Item 1" Margin="5 0 0 0" />
                    </StackPanel>
                </ComboBoxItem.Content>
            </ComboBoxItem>
            <ComboBoxItem >
                <ComboBoxItem.Content>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Images/ComboItem.png" />
                        <TextBlock Text="Item 2" Margin="5 0 0 0" />
                    </StackPanel>
                </ComboBoxItem.Content>
            </ComboBoxItem>
            <ComboBoxItem >
                <ComboBoxItem.Content>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Images/ComboItem.png" />
                        <TextBlock Text="Item 3" Margin="5 0 0 0" />
                    </StackPanel>
                </ComboBoxItem.Content>
            </ComboBoxItem>
            <ComboBoxItem >
                <ComboBoxItem.Content>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Images/ComboItem.png" />
                        <TextBlock Text="Item 4" Margin="5 0 0 0" />
                    </StackPanel>
                </ComboBoxItem.Content>
            </ComboBoxItem>
            <ComboBoxItem >
                <ComboBoxItem.Content>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Images/ComboItem.png" />
                        <TextBlock Text="Item 5" Margin="5 0 0 0" />
                    </StackPanel>
                </ComboBoxItem.Content>
            </ComboBoxItem>
        </ComboBox>

在此主题中,我们学习了如何在同一个控件中实现模板。您可以看到在每个控件中实现模板都很容易,但是这样做很繁琐,因为我们必须为我们需要的任何控件编写这种类型的代码。

通过 XAML 在资源中实现模板 

在我们的解决方案 (UsefulThingPart1.sln) 中,我们必须添加一个名为 TemplatesResourcesXAML 的新项目,我们在其中添加两个控件。首先,从 Toolbox 将一个 Button 拖放到您的 MainPage.xaml 页面中。生成的 XAML 代码如下:

<Button Content="Click Me!" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click"/>  

如果我们运行项目 (F5),我们将看到一个文本为“Click Me!”的 Button,如果我们单击该按钮,我们将看到 MessageBox

此时,我们需要添加两条单独的 XAML 行。第一个对应于 User Control (如果使用,则为 Page) 的 Resources。所以,只需添加这行代码:

<UserControl.Resources>
        <DataTemplate x:Key="buttonTemplate">
            <StackPanel Orientation="Horizontal">
                <Image Source="Images/Click.png" Width="32" Height="32"
                           Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Left" />
                <!--Add Binding to show any text added in the button Content property-->
                <TextBlock Text="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Center"  />
            </StackPanel>
        </DataTemplate> 
      
        <DataTemplate x:Key="comboTemplate">
            <StackPanel Orientation="Horizontal">
                <Image Source="Images/ComboItem.png" />
                <TextBlock Text="{Binding}" Margin="5 0 0 0" />
            </StackPanel>
        </DataTemplate>       
    </UserControl.Resources>  

因此,我们必须为 ButtonComboBox 添加 xaml。让我们看看下面的代码:

<Button Content="Click Me!" ContentTemplate="{StaticResource buttonTemplate}" Margin="0 30 0 0"
                HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click"/>

        <ComboBox HorizontalAlignment="Left" Margin="0,130,0,0" VerticalAlignment="Top" >
            <ComboBoxItem Content="Item 1" ContentTemplate="{StaticResource comboTemplate}" />
            <ComboBoxItem Content="Item 2" ContentTemplate="{StaticResource comboTemplate}" />
            <ComboBoxItem Content="Item 3" ContentTemplate="{StaticResource comboTemplate}" />
            <ComboBoxItem Content="Item 4" ContentTemplate="{StaticResource comboTemplate}" />
            <ComboBoxItem Content="Item 5" ContentTemplate="{StaticResource comboTemplate}" />
        </ComboBox> 

在上面展示的示例中,我使用了 ContentTemplate,因为我明确添加了 ComboBoxItem。但是,如果我们从数据库获取数据,我们可以在 ComboBox 元素中直接添加 ItemTemplate,将其绑定到资源中的 DataTemplate

通过代码隐藏在 Button 和 ComboBox 中实现模板

在我们的解决方案 (UsefulThingPart1.sln) 中,我们必须添加一个名为 TemplatesCSharp 的新项目,我们在其中添加两个控件。首先,从 Toolbox 将一个 Button 拖放到 MainPage.xaml 页面中。生成的 XAML 代码如下:

<Button Content="Click Me!" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click" Margin="0"/> 

如果我们运行项目 (F5),我们将看到一个文本为“Click Me!”的 Button,如果我们单击该按钮,我们将看到 MessageBox。

现在是时候创建另一个按钮了。我们的想法是添加一个图标,然后是左对齐和居中的文本。在这种情况下,我们必须在 C# 文件 (MainPage.xaml.cs) 中添加一些代码行。

XAML 代码如下:

<Button x:Name="buttonTemplate" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click" Margin="0 30 0 0"/>

这是用于应用 DataTemplate 的 C# 私有方法:

 private DataTemplate SetButtonContent()
        {
            StringBuilder sb = new StringBuilder();
            
            sb.Append("<DataTemplate "); 
            sb.Append("xmlns='http://schemas.microsoft.com/winfx/");
            sb.Append("2006/xaml/presentation' "); 
            sb.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' >");
            sb.Append("<StackPanel Orientation='Horizontal'> ");
            sb.Append("<Image Source='Images/Click.png' Width='32' Height='32' ");
            sb.Append("Stretch='Uniform' VerticalAlignment='Center' HorizontalAlignment='Left' /> ");
            sb.Append("<TextBlock Text='Click Me!' HorizontalAlignment='Left' VerticalAlignment='Center'  />");
            sb.Append("</StackPanel> </DataTemplate>");
            
            DataTemplate dt = XamlReader.Load(sb.ToString()) as DataTemplate;
            return dt;
        }

所以,私有方法可以由构造函数调用。我给您展示一下: 

  this.buttonTemplate.ContentTemplate = this.SetButtonContent();

再次运行项目 (F5),我们将看到带有模板和不带模板的两个按钮。

现在我们尝试添加一个 ComboBox,我们在其中显示一些选项,只需编写以下 XAML 代码:

 <ComboBox HorizontalAlignment="Left" Margin="0,80,0,0" VerticalAlignment="Top" >
      <ComboBoxItem Content="Item 1" />
      <ComboBoxItem Content="Item 2" />
      <ComboBoxItem Content="Item 3" />
      <ComboBoxItem Content="Item 4" />
      <ComboBoxItem Content="Item 5" />
</ComboBox> 

添加 ComboBox 后,我们可以在每个 ComboBoxItem 中添加模板,但在这里我们将通过代码隐藏填充 ComboBox

 <ComboBox x:Name="comboTemplate" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0 100 0 0" />

这是用于应用 DataTemplate 的 C# 私有方法:

 private DataTemplate SetComboBoxContentTemplate()
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("<DataTemplate ");
            sb.Append("xmlns='http://schemas.microsoft.com/winfx/");
            sb.Append("2006/xaml/presentation' ");
            sb.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' >");
            sb.Append("<StackPanel Orientation='Horizontal'> ");
            sb.Append("<Image Source='Images/ComboItem.png' /> ");
            sb.Append("<TextBlock Text='{Binding}' Margin='5 0 0 0' /> ");
            sb.Append("</StackPanel> </DataTemplate>");

            DataTemplate dt = XamlReader.Load(sb.ToString()) as DataTemplate;
            return dt;
        }

所以,私有方法可以由构造函数调用(在源代码中,您将看到另一个私有方法,用于调用这些代码行以使其更有条理)。我给您展示一下:

 this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 1", ContentTemplate = this.SetComboBoxContentTemplate() });
 this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 2", ContentTemplate = this.SetComboBoxContentTemplate() });
 this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 3", ContentTemplate = this.SetComboBoxContentTemplate() });
 this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 4", ContentTemplate = this.SetComboBoxContentTemplate() });
 this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 5", ContentTemplate = this.SetComboBoxContentTemplate() });

当您需要在运行时更改 Template 时,此实现可能非常有用,或者只是如果您想像我一样编写一些代码。  

通过 XAML 在资源中实现模板

在我们的解决方案 (UsefulThingPart1.sln) 中,我们必须添加一个名为 TemplatesResourcesCSharp 的新项目,我们在其中添加两个控件。首先,从 Toolbox 将一个 button 拖放到您的 MainPage.xaml 页面中。生成的 XAML 代码如下:

<Button<span style="white-space: pre-wrap; "> </span>Content="Click Me!"<span style="white-space: pre-wrap; "> </span>HorizontalAlignment="Left"<span style="white-space: pre-wrap; "> </span>VerticalAlignment="Top"<span style="white-space: pre-wrap; "> </span>Click="Button_Click"/>

如果我们运行项目 (F5),我们将看到一个文本为“Click Me!”的 Button,如果我们单击该按钮,我们将看到 MessageBox

此时,我们需要添加两条单独的 XAML 行。第一个对应于 User Control (如果使用,则为 Page) 的 Resources。所以,只需添加这行代码:

    <UserControl.Resources>
        <DataTemplate x:Key="buttonTemplate">
            <StackPanel Orientation="Horizontal">
                <Image Source="Images/Click.png" Width="32" Height="32" 
                           Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Left" />
                <!--Add Binding to show any text added in the button Content property-->
                <TextBlock Text="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Center"  />
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="comboTemplate">
            <StackPanel Orientation="Horizontal">
                <Image Source="Images/ComboItem.png" />
                <TextBlock Text="{Binding}" Margin="5 0 0 0" />
            </StackPanel>
        </DataTemplate>
    </UserControl.Resources>

因此,我们必须在代码隐藏中添加 C# 代码,以便为 ButtonComboBox 应用这些资源。让我们看看下面的代码:

this.btnTemplate.ContentTemplate = this.Resources["buttonTemplate"] as DataTemplate;
this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 1", ContentTemplate = this.Resources["comboTemplate"] as DataTemplate });
            this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 2", ContentTemplate = this.Resources["comboTemplate"] as DataTemplate });
            this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 3", ContentTemplate = this.Resources["comboTemplate"] as DataTemplate });
            this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 4", ContentTemplate = this.Resources["comboTemplate"] as DataTemplate });
            this.comboTemplate.Items.Add(new ComboBoxItem() { Content = "Item 5", ContentTemplate = this.Resources["comboTemplate"] as DataTemplate }); 

通过 XAML 和代码隐藏实现本地化

第一步是定义我们 Assembly 的区域性,这将是项目的默认语言。因此,我们必须右键单击项目的 Properties,然后在 Silverlight 选项卡中查找 Assembly Information… 按钮,单击它。之后,执行以下操作(就我而言,我选择了英语 - 美国):

此时,我们需要添加一个新类型的 Resource 文件。为此,我们需要右键单击项目并选择 Add -> New Item… 然后为文件命名。以下屏幕截图显示了此处解释的步骤:

现在我们在生成的文件中添加一些资源。请记住将此文件的 Access Modifier 设置为 Public,因为 .NET 需要为资源生成相应的代码。因此,在默认资源文件(本例中为英语)中,.NET 为资源文件中的每个条目生成属性。

所以,在我们的 MainPage.xaml.cs 中,我们将第一个 TextBlockText 属性设置为资源的 TextBlockCSharp 属性。看这里:

//Set the text with the property of Resource, called by Name
this.textCSharp.Text = MainPage.TextBlockCSharp; 

创建一个名为 ResourceStrings 的类,我们将用于 XAML 文件中的资源。这样,我们总会有一个用于确定字符串的属性。所以,这是文件的内容:

namespace Localization
{
    public class ResourceStrings
    {
        public ResourceStrings() { }
 
        //Instantiate the Class MainPageResource
        private static MainPageResource mainPageResource = new MainPageResource();
 
        //Create the property for Resource
        public MainPageResource MainPageResource { get { return mainPageResource; } }
    }
} 

现在,在我们的 XAML 文件(任何文件)中,我们可以通过以下语法访问资源:

<TextBlock Margin="0 30 0 0" Text="{Binding Path=MainPageResource.TextBlockXAML, Source={StaticResource ResourceStrings}}" />  

此时,我们将收到一个错误,因为我们没有将 Resource 设置为 Application.Resources。为此,请打开 App.xaml 文件。

<local:ResourceStrings xmlns:local="clr-namespace:Localization"
                           x:Key="ResourceStrings" /> 

在代码隐藏中,我们必须添加以下代码行(在 Application_Startup 事件中),以便本地化能够正常工作:

Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture =
             new System.Globalization.CultureInfo("es-PY"); 

在上面的代码中,我们需要替换 CultureInfo 构造函数中的字符串。在示例中,我们可以输入 es-PY(如果您想在我们的文本块中看到西班牙语 - 巴拉圭语)或任何其他语言以显示默认语言(英语)。

关注点

希望本教程能帮助您了解使用 Silverlight 可以做的一些有用的事情。

您喜欢这个教程吗?别忘了分享给其他人,评分,评论并将其加入书签 =)

下一步?

您将在本网站未来的文章中找到更多关于 Silverlight 的有用信息。敬请关注!

您也可以访问我的 西班牙语博客,查看本文的西班牙语版本。

© . All rights reserved.