• Silverlight WCF RIA服务(三十五)身份验证、角色、个性化 6


    演练:在Silverlight Business应用程序中使用身份验证服务 Silverlight Business应用程序模板创建的解决方案自动允许身份验证(验证模式为Forms),角色和个性化功能。解决方案包含了数据表格来登录已经存在的用户和注册新用户。我们不用写额外的代码就可以使用这些特性。
      

    演练:在Silverlight Business应用程序中使用身份验证服务
    Silverlight Business应用程序模板创建的解决方案自动允许身份验证(验证模式为Forms),角色和个性化功能。解决方案包含了数据表格来登录已经存在的用户和注册新用户。我们不用写额外的代码就可以使用这些特性。我们也可以通过定义角色、个性化属性来自定义解决方案。

    在本演练中,我们将学习如何在Silverlight Business应用程序中使用身份验证、角色和个性化功能。我们将根据用户的凭证来限制对某些域操作的访问,并根据用户的偏好来定制用户界面。我们将使用ASP.NET网站管理工具来管理角色和用户。

    创建网站、用户、角色
    我们可以使用Silverlight Business应用程序模板提供的特性,来快速实施验证功能。在下面的章节,我们使用ASP.NET配置工具来创建用户和角色,并登陆此用户。我们还通过Silverlight Business应用程序提供的注册表格来注册新用户。

    1. 在Visual Studio中,选择"文件->新建->项目"."新建项目"对话框打开。
    2. 选择Silverlight项目类型。
    3. 选择Silverlight Business Application模板,并命名为ExampleBusinessApplication.

    4. 点击"OK".注意创建的项目结构。这个SL客户端项目中在Views文件夹中包含了SL页面。这些页面允许登陆用户和注册新用户。
    5. 打开ASP.NET 网站管理工具。(首先,在资源管理器中,选择服务端项目,然后打开ASP.NET配置工具。
    6. 在项目菜单中,选择ASP.NET Configuration.如果在项目菜单中,看不到ASP.NET Configuration选项,有可能是选择了客户端项目。

    7.在ASP.NET网站管理工具中选择"安全"标签。

    8. 在"角色"的部分,点击"创建或管理角色"链接。
    9. 添加一个名为Managers的角色,并点击"添加角色"按钮。

    10. 在右下角,点击"返回"按钮。
    11. 在“用户"的部分,点击"创建用户"按钮。
    12. 使用下面的值来创建新用户,并选择Managers角色复选框。
    - User Name : CustomerManager
    - Password : P@ssword
    - E-mail : someone@example.com
    - Security Question : Favorite color?
    - Security Answer : Blue
    - Managers role : selected

    13. 点击"创建用户"按钮。
    14. 关闭ASP.NET网站管理工具。
    15. 运行解决方案。应用程序的首页将会显示在web浏览器中。
    16. 在页面的右上角,点击”登陆"链接。登陆窗口将会出现。
    17. 为用户名称输入CustomerManager,为密码输入p@ssword,并点击"OK"按钮。

    现在我们就登陆这个用户了,注意到在页面右上角出现文本"Welcome CustomerManager"。
    18. 点击"登出"按钮。这时我们就不再以CustomerManager登陆了。
    下面的步骤,我们通过注册表格创建一个新用户。
    19. 再次点击"登陆"链接。
    20. 在登陆对话框中,点击"现在就注册"链接。注册表格就会出现了。
    21. 用下面的信息填充注册表。
    Username: SalesUser

    Friendly name: SalesUser

    Email: someone@example.com

    Password: P@ssword

    Security Question: What was the color of your first car?

    Security Answer: Green

    22. 点击"OK",创建一个新用户。注意,我们现在已经作为SalesUser登陆了。
    23. 关闭浏览器。
    24. 打开ASP.NET网站管理工具,点击"安全"标签。注意到已经有了两个用户和角色,即使我们只创建了一个角色。
    25. 点击“创建或管理角色”,注意到Managers和Registered Users角色。Registered User角色是Business应用程序模板自动生成的。

    26. 对"Registered Users",点击"管理"链接。注意,通过应用程序添加的名为SalesUser的用户已经在Registered Users角色中了。
    27. 关闭ASP.NET网站管理工具。

    定义访问权限和个性化属性

    我们通过为域服务应用RequiresAuthenticationAttribute和RequiresRoleAttribute属性,来限制对域服务的访问。如果域操作没有属性,对所有用户有效。在域操作上添加属性,并不能阻止用户调用域操作。只是没有所需凭证的用户会收到一个异常。

    根据角色限制显示数据
    1. 在资源管理器中,在服务端项目中,点击App_Data文件夹,选择"添加->已存在项"。
    2. 在"添加已存在项"对话框中,添加AdventureWorksLT示例数据库。
    3. 在服务端,添加一个新项,并选择ADO.NET Entity Data Model模板。
    4. 命名模型为AdventureWorksModel.edmx,并点击"添加"."实体数据模型向导"将会出现。
    5. 选择"从数据库生成"选项,并点击"下一步".
    6. 选择AdventureWorksLT数据库,并点击"下一步"。
    7. 从数据库对象列表中,选择Customer,Product,以及SalesOrderHeader表,然后点击"完成"。实体数据模型将会出现在设计器中。
    8. 生成解决方案。
    9. 在服务端,添加一个新项,并选择Domain Service Class模板。
    10. 命名为AdventureWorksDomainService,然后点击"添加"。
    11. 在"添加新域服务类"对话框中,选择Customer,Product和SalesOrderHeader实体。

    12. 点击"OK"以完成创建域服务。
    13. 在AdventureWorksDomainService类中,对GetSalesOrderHeader方法添加RequiresAuthenticationAttribute属性。
     

    1
    2
    3
    4
    5
    6
    7
    [RequiresAuthentication()]
    public IQueryable<SALESORDERHEADER> GetSalesOrderHeaders()
    {
        return this.ObjectContext.SalesOrderHeaders;
    }


    14. 对GetCustomers方法添加RequiresRoleAttribute属性,并设置所需的角色为"Managers"。
     

    1
    2
    3
    4
    5
    6
    7
    [RequiresRole("Managers")]
    public IQueryable<CUSTOMER> GetCustomers()
    {
        return this.ObjectContext.Customers;
    }


    GetProducts方法对所有用户都可用,GetSalesOrderHeader只对验证用户可用,GetCustomers方法只对属于Managers角色的用户可用。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    [EnableClientAccess()]
    public class AdventureWorksDomainService : LinqToEntitiesDomainService<ADVENTUREWORKSLT_DATAENTITIES>
    {
        [RequiresRole("Managers")]
        public IQueryable<CUSTOMER> GetCustomers()
        {
            return this.ObjectContext.Customers;
        }
     
        public IQueryable<PRODUCT> GetProducts()
        {
            return this.ObjectContext.Products;
        }
     
        [RequiresAuthentication()]
        public IQueryable<SALESORDERHEADER> GetSalesOrderHeaders()
        {
            return this.ObjectContext.SalesOrderHeaders;
        }
    }



    下面我们在Web.config文件中定义个性法属性。当我们把属性添加到服务端的用户类时,将会为客户端项目生成对应的属性。

    1. 在服务端项目,打开Web.config文件。
    2. 在 元素内,添加名为DefaultRows的个性化属性。这个属性将保持用户对显示的数据数量的偏爱。
     

    1
    2
    3
    4
    5
    6
    7
    8
    <PROFILE>
      <PROPERTIES>
        <ADD name="FriendlyName" />
        <ADD name="DefaultRows" defaultValue="10" type="System.Int32" />
      </PROPERTIES>
    </PROFILE>


    3. 保存Web.config文件。
    4. 在服务端项目中,展开Models文件夹。
    5. 打开User.cs或User.vb文件,添加名为DefaultRows属性。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    namespace ExampleBusinessApplication.Web
    {
        using System.Runtime.Serialization;
        using System.Web.Ria.ApplicationServices;
     
        public partial class User : UserBase
        {
            [DataMember]
            public string FriendlyName { getset; }
     
            public int DefaultRows { getset; }
        }
    }



    从客户端使用身份验证服务
    在调用有限制权限的域操作时,我们应该对用户检查所需的凭证。否则,将会抛出一个异常。在下面的部分,我们将检查用户的凭证,并根据用户的凭证来填充一个到三个DataGrid控件。我们会根据用户个性化中的属性来得到显示的记录数量。对没有验证的用户,默认的值是10。这部分没有让用户更改DefaultRows个性化属性的方式,不过在以后的部分会添加这个方式。

    添加一个Silverlight页面来显示数据
    1. 在客户端,在Views文件夹中添加新项。
    2. 选择Silverlight Page模板,并命名为Reports.xaml。
    3. 打开MainPage.xaml文件,并名为Link2的超链接按钮下面添加一个指向Reports页面的链接。
     

    1
    2
    3
    4
    5
    6
    <RECTANGLE x:Name="Divider2" />
     
    <HYPERLINKBUTTON x:Name="Link3"
           NavigateUri="/Reports" TargetName="ContentFrame" Content="{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}"/>


    4. 在Assets\Resources文件夹内,打开ApplicationString.resx文件。
    5. 添加一个新的名为ReportsPageTitle的字符串资源,并设置值为Reports。

    6. 保存并关闭ApplicationString.resx文件。
    7. 打开Reports.xaml文件,并添加如下XAML到Grid元素内。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <SCROLLVIEWER x:Name="PageScrollViewer">
        <STACKPANEL x:Name="ContentStackPanel">
            <TEXTBLOCK x:Name="HeaderText"
                       Text="{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}"/>
            <TEXTBLOCK x:Name="ContentText"
                       Text="Display reports based on user permissions"/>
     
        </STACKPANEL>
    </SCROLLVIEWER>


    8. 拖拽三个DataGrid控件到名为ContentStackPanel的stack面板内。当我们从工具栏中拖拽DataGrid控件时,会在项目中添加一个对System.Windows.Controls.Data程序集的应用,并在页面内添加System.Windows.Controls命名空间。
    9. 命名DataGrid控件为ProductsGrid、SalesOrdersGrid、CustomerGrid。
    10. 对每个DataGrid控件,设置Margin为5.
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <NAVIGATION:PAGE <br x:Class="ExampleBusinessApplication.Views.Reports" />           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
               mc:Ignorable="d"
               xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
               d:DesignWidth="640" d:DesignHeight="480"
               Title="Reports Page" >
        <GRID x:Name="LayoutRoot">
            <SCROLLVIEWER x:Name="PageScrollViewer">
                <STACKPANEL x:Name="ContentStackPanel">
                    <TEXTBLOCK x:Name="HeaderText"
                               Text="{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}"/>
                    <TEXTBLOCK x:Name="ContentText"
                               Text="Display reports based on user permissions"/>
                    <?xml:namespace prefix data ns "http://www.google.com/2005/gml/data" /><data:DataGrid Margin="5" Name="ProductsGrid"></data:DataGrid>
                    <data:DataGrid Margin="5" Name="SalesOrdersGrid"></data:DataGrid>
                    <data:DataGrid Margin="5" Name="CustomersGrid"></data:DataGrid>
                </STACKPANEL>
            </SCROLLVIEWER>
        </GRID>
    </NAVIGATION:PAGE>


    11. 打开Reports.xaml.cs或Reports.xaml.vb。
    12. 对c#,用using添加System.Windows.Ria,System.Windows.Ria.ApplicationServices,ExampleBusinessApplication.Web,和ExampleBusinessApplication.Resources命名空间。
    13. 创建AdventureWorksDomainService的名为context的实例,并创建一个名为numberOfRows的变量来保存检索的记录数量。
     

    1
    2
    3
    4
    private AdventureWorksDomainContext context = new AdventureWorksDomainContext();
    int numberOfRows = 10;


    14. 添加一个名为LoadRestrictedReports的方法,这个方法调用GetSalesOrderHeaderQuery方法和GetCustomerQuery方法。如果用户属于Managers角色,就显示对应的带结果的数据表格。
    如果没有所需凭证的用户调用一个域操作时,域操作会返回一个异常。我们可以通过在调用域操作之前检查凭证来避免这种情况。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    private void LoadRestrictedReports()
    {
        LoadOperation<SALESORDERHEADER> loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows));
        SalesOrdersGrid.ItemsSource = loadSales.Entities;
        SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible;
     
        if (WebContext.Current.User.IsInRole("Managers"))
        {
            LoadOperation<CUSTOMER> loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows));
            CustomersGrid.ItemsSource = loadCustomers.Entities;
            CustomersGrid.Visibility = System.Windows.Visibility.Visible;
        }
        else
        {
            CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
        }
    }


    15. 添加名为LoadReports的方法来检测是否用户已验证,如果已验证,就调用LoadRestricteReports方法。它还检索名为DefaultRows的个性化属性,并对User对象的PropertyChanged事件添加事件处理程序。最后,对所有用户调用GetProductsQuery方法。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    private void LoadReports()
    {
        if (WebContext.Current.User.IsAuthenticated)
        {
            numberOfRows = WebContext.Current.User.DefaultRows;
            WebContext.Current.User.PropertyChanged += newSystem.ComponentModel.PropertyChangedEventHandler(User_PropertyChanged);
            LoadRestrictedReports();
        }
        else
        {
            CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
            SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed;
        }
     
        LoadOperation<PRODUCT> loadProducts = context.Load(context.GetProductsQuery().Take(numberOfRows));
        ProductsGrid.ItemsSource = loadProducts.Entities;
    }


    16. 对PropertyChanged事件添加事件处理程序,保证在DefaultRows属性改变时调用LoadReports方法。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void User_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "DefaultRows")
        {
            LoadReports();
        }
    }


    17. 为LoggedIn和LoggedOut事件添加事件处理方法,并根据用户凭证的状况装载或隐藏数据。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
    {
        LoadReports();
    }
     
    void Authentication_LoggedOut(object sender, AuthenticationEventArgs e)
    {
        CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
        SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed;
    }


    18. 在构造函数内添加下面的代码:
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public Reports()
    {
        InitializeComponent();
     
        this.Title = ApplicationStrings.ReportsPageTitle;
     
        WebContext.Current.Authentication.LoggedIn += newSystem.EventHandler<AUTHENTICATIONEVENTARGS>(Authentication_LoggedIn);
        WebContext.Current.Authentication.LoggedOut += newSystem.EventHandler<AUTHENTICATIONEVENTARGS>(Authentication_LoggedOut);
     
        LoadReports();
    }


    以下是完整代码
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Navigation;
    using System.Windows.Ria;
    using System.Windows.Ria.ApplicationServices;
    using ExampleBusinessApplication.Web;
    using ExampleBusinessApplication.Resources;
     
    namespace ExampleBusinessApplication.Views
    {
        public partial class Reports : Page
        {
            private AdventureWorksDomainContext context = new AdventureWorksDomainContext();
            int numberOfRows = 10;
     
            public Reports()
            {
                InitializeComponent();
     
                this.Title = ApplicationStrings.ReportsPageTitle;
     
                WebContext.Current.Authentication.LoggedIn += newSystem.EventHandler<AUTHENTICATIONEVENTARGS>(Authentication_LoggedIn);
                WebContext.Current.Authentication.LoggedOut += newSystem.EventHandler<AUTHENTICATIONEVENTARGS>(Authentication_LoggedOut);
     
                LoadReports();
            }
     
            private void LoadReports()
            {
                if (WebContext.Current.User.IsAuthenticated)
                {
                    numberOfRows = WebContext.Current.User.DefaultRows;
                    WebContext.Current.User.PropertyChanged += newSystem.ComponentModel.PropertyChangedEventHandler(User_PropertyChanged);
                    LoadRestrictedReports();
                }
                else
                {
                    CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
                    SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed;
                }
     
                LoadOperation<PRODUCT> loadProducts = context.Load(context.GetProductsQuery().Take(numberOfRows));
                ProductsGrid.ItemsSource = loadProducts.Entities;
            }
     
            private void LoadRestrictedReports()
            {
                LoadOperation<SALESORDERHEADER> loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows));
                SalesOrdersGrid.ItemsSource = loadSales.Entities;
                SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible;
     
                if (WebContext.Current.User.IsInRole("Managers"))
                {
                    LoadOperation<CUSTOMER> loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows));
                    CustomersGrid.ItemsSource = loadCustomers.Entities;
                    CustomersGrid.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
                }
            }
     
            void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
            {
                LoadReports();
            }
     
            void Authentication_LoggedOut(object sender, AuthenticationEventArgs e)
            {
                CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
                SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed;
            }
     
            void User_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                if (e.PropertyName == "DefaultRows")
                {
                    LoadReports();
                }
            }
        }
    }


    19. 运行解决方案。
    20. 点击Reports链接。注意到,当我们没登陆时,只有产品表显示在报告页面。
    21. 点击"登陆"链接,并以SalesUser登陆。会发现,产品和销售订单表显示出来。

    22. 登出并以CustomerManager登陆。会发现,三个表都显示了。
    23. 关闭web浏览器。

    添加一个窗口来设置个性化属性
    我们可以通过添加一个子窗口来允许用户编辑DefaultRows个性属性。当值改变后,我们调用SaveUser方法来把值保存到数据源。我们通过当前WebContext实例的User对象上的属性来检索当前的值。
    1. 在客户端,在Views文件夹中添加新项。
    2. 选择Silverlight Child Window模板,并命名为ProfileWindow.xaml。

    3. 点击"添加"按钮。
    4. 在ProfileWindow.xaml文件内,在Grid.RowDefinitions元素后添加XAML,来添加一个下拉列表选择要在报表中显示的行数。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <STACKPANEL Grid.Row="0" Orientation="Horizontal">
        <TEXTBLOCK Text="Number of rows to display for reports: "></TEXTBLOCK>
        <COMBOBOX x:Name="defaultRows" VerticalAlignment="Top" Height="20">
            <COMBOBOXITEM Content="1"></COMBOBOXITEM>
            <COMBOBOXITEM Content="2"></COMBOBOXITEM>
            <COMBOBOXITEM Content="3"></COMBOBOXITEM>
            <COMBOBOXITEM Content="4"></COMBOBOXITEM>
            <COMBOBOXITEM Content="5"></COMBOBOXITEM>
            <COMBOBOXITEM Content="6"></COMBOBOXITEM>
            <COMBOBOXITEM Content="7"></COMBOBOXITEM>
            <COMBOBOXITEM Content="8"></COMBOBOXITEM>
            <COMBOBOXITEM Content="9"></COMBOBOXITEM>
            <COMBOBOXITEM Content="10"></COMBOBOXITEM>
            <COMBOBOXITEM Content="15"></COMBOBOXITEM>
            <COMBOBOXITEM Content="20"></COMBOBOXITEM>
        </COMBOBOX>
    </STACKPANEL>


    5. 设置ChildWindow的Title属性为Select References。
    6. 在ProfileWindow.xaml.cs中,添加下面的代码来检索和设置个性化属性。
     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public partial class ProfileWindow : ChildWindow
    {
        public ProfileWindow()
        {
            InitializeComponent();
     
            string userDefaultRows = WebContext.Current.User.DefaultRows.ToString();
            foreach (ComboBoxItem cbi in defaultRows.Items)
            {
                if (cbi.Content.ToString() == userDefaultRows)
                {
                    defaultRows.SelectedItem = cbi;
                    break;
                }
            }
        }
     
        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            int newSelection = int.Parse(defaultRows.SelectionBoxItem.ToString());
            if (newSelection != WebContext.Current.User.DefaultRows)
            {
                WebContext.Current.User.DefaultRows = newSelection;
                WebContext.Current.Authentication.SaveUser(true);
            }
            this.DialogResult = true;
        }
     
        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }
    }


    7. 如果是VB,添加Imports命令引用System.Windows.Controls和System.Windows命名空间。
    8. 展开Views\Login文件夹,并打开LoginStatus.xaml文件。
    9. 添加一个指向profile文件的设置链接,在Logout按钮前添加下面的XAML
     

    1
    2
    3
    4
    <BUTTON x:Name="SettingsButton" Margin="0,0,0,0" Content="settings"Click="SettingsButton_Click"></BUTTON>
    <TEXTBLOCK Text="  |  " />


    10. 在LoginStatus.xaml.cs文件内,为设置链接添加点击事件处理方法。
     

    1
    2
    3
    4
    5
    6
    7
    private void SettingsButton_Click(object sender, RoutedEventArgs e)
    {
        ExampleBusinessApplication.Views.ProfileWindow settingsWindow = newExampleBusinessApplication.Views.ProfileWindow();
        settingsWindow.Show();
    }


    11. 运行解决方案。
    12. 以CustomerManager或SalesUser登陆,注意到在登陆状态栏,现在包含一个"设置"的链接。

    13. 点击"设置"链接,并设置默认的报表显示行数。

    14. 打开报表页面,会注意到DataGrid现在包含我们所选的行数。

    Powered By D&J (URL:http://www.cnblogs.com/Areas/)
  • 相关阅读:
    【LeetCode】96.Unique Binary Search Trees
    【LeetCode】136.Single Number
    VirtualBox下Linux加载Windows的共享目录
    Macbook上Windows的触摸板设置工具
    [转]太岁三煞五黄
    [转]UI、GUI、UE、UX、ID、UED、UCD的区别
    紫微斗数:命主和身主
    [转]如何降低二手烟的危害
    [转]从第六十三卦到第六十四卦
    Mac显示和隐藏隐藏文件
  • 原文地址:https://www.cnblogs.com/Areas/p/2172201.html
Copyright © 2020-2023  润新知