GVKun编程网logo

SilverLight Tip 1 : Validation

9

此处将为大家介绍关于SilverLightTip1:Validation的详细内容,此外,我们还将为您介绍关于CharlieCalvert:SilverlightSimpleAnimation、Sil

此处将为大家介绍关于SilverLight Tip 1 : Validation的详细内容,此外,我们还将为您介绍关于Charlie Calvert: Silverlight Simple Animation、Silverlight 4 + RIA Services之商业应用系列----2 Updating&Validation、Silverlight Navigation-Silverlight页面间自定义导航、Silverlight ValidatesOnException默认消息本地化的有用信息。

本文目录一览:

SilverLight Tip 1 : Validation

SilverLight Tip 1 : Validation

1:SL的数据验证和WPF的不同

首先,很遗憾,SL中不再存在ValidationRules,要在SL中绑定时验证数据,并且显示在UI,只能依赖于NotifyOnValidationError=True,ValidatesOnExceptions=True这两个属性,如下:

image

如果要查看WPF的数据验证的方式,可以查看该文《WPF快速指导5:验证》。

2:一般情况下的验证

一般情况下,UI绑定数据类型的属性,如在上图中,绑定的就是Name和Age,它在UI的viewmodeL中,如下:

    public class MainPageVM : INotifyPropertyChanged
    {
        public MainPageVM()
        {
        }

        private string name = "luminji";

        public string Name
        {
            get { return name; }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new Exception("姓名不能为空");
                }
                name = value;
                OnPropertyChanged("Name");
            }
        }

        private int age = 1;

        public int Age
        {
            get { return age; }
            set
            {
                if (value > 100)
                {
                    throw new Exception("年龄必须小与100");
                }
                age = value;
                OnPropertyChanged("Age");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler pceh = PropertyChanged;
            if (pceh != null)
            {
                pceh(this,new PropertyChangedEventArgs(propertyName));
            }
        }
       
    }

采用UI直接绑定VM的属性,如果Age>100,则UI会提示出现输入有误。

 

3:绑定实体类型

不过,如果属性很多,我们就会考虑绑定实体类型。如User,而这个实体类,是在服务器端的,形如:

    public class User
    {
        private string name = "luminji";

        public string Name
        {
            get { return name; }
            set
            {
                name = value;
            }
        }

        private int age = 1;

        public int Age
        {
            get { return age; }
            set
            {
                age = value;
            }
        }
    }

比如,我们使用的是Ria Service。Ria Service有可能是从DAL层获取数据并开放接口给客户端。我们都知道,客户端的代码都是自动生成的,自动生成的代码在SL项目的Generated_Code目录下的(SL项目名).Web.g.cs文件下。所以,最终User类型在客户端的代理形式为:

    /// <summary>
    /// The 'User' entity class.
    /// </summary>
    [DataContract(Namespace="http://schemas.datacontract.org/2004/07/SilverlightApplication3.Web.Model")]
    public sealed partial class User : Entity
    {
        
        private int _age;
        
        private string _name;
        
        #region Extensibility Method DeFinitions

        /// <summary>
        /// This method is invoked from the constructor once initialization is complete and
        /// can be used for further object setup.
        /// </summary>
        partial void OnCreated();
        partial void OnAgeChanging(int value);
        partial void OnAgeChanged();
        partial void OnNameChanging(string value);
        partial void OnNameChanged();

        #endregion
        
        
        /// <summary>
        /// Initializes a new instance of the <see cref="User"/> class.
        /// </summary>
        public User()
        {
            this.OnCreated();
        }
        
        /// <summary>
        /// Gets or sets the 'Age' value.
        /// </summary>
        [DataMember()]
        public int Age
        {
            get
            {
                return this._age;
            }
            set
            {
                if ((this._age != value))
                {
                    this.OnAgeChanging(value);
                    this.RaiseDataMemberChanging("Age");
                    this.ValidateProperty("Age",value);
                    this._age = value;
                    this.RaiseDataMemberChanged("Age");
                    this.OnAgeChanged();
                }
            }
        }
        
        /// <summary>
        /// Gets or sets the 'Name' value.
        /// </summary>
        [DataMember()]
        [Editable(false,AllowInitialValue=true)]
        [Key()]
        [roundtripOriginal()]
        public string Name
        {
            get
            {
                return this._name;
            }
            set
            {
                if ((this._name != value))
                {
                    this.OnNameChanging(value);
                    this.ValidateProperty("Name",value);
                    this._name = value;
                    this.RaisePropertyChanged("Name");
                    this.OnNameChanged();
                }
            }
        }
        
        /// <summary>
        /// Computes a value from the key fields that uniquely identifies this entity instance.
        /// </summary>
        /// <returns>An object instance that uniquely identifies this entity instance.</returns>
        public override object GetIdentity()
        {
            return this._name;
        }
    }

这个时候,如果我们在UI中继续绑定这个实体类型,势必会丢掉UI异常通知的行为,因为,显然,我们不能跑到这个客户端的代理类中throw new Exception("姓名不能为空"); ,那会在下一次代码自动生成的时候被覆盖掉。

4:解决方案之建立映射

一种解决方案是我们的UI仍旧不绑定实体类型,而是为类型的属性在viewmodel中建立一一映射的关系,如下:

    public class MainPageVM : INotifyPropertyChanged
    {
        public MainPageVM()
        {
            user = new User();
            serviceUser = new DomainServiceUser();
            serviceUser.Load<User>(serviceUser.GetAUserQuery(),new Action<System.ServiceModel.domainservices.Client.LoadOperation<User>>(this.GetAUserCallBack),null);
        }

        DomainServiceUser serviceUser;
        User user;
        
        
        void GetAUserCallBack(LoadOperation<User> arg)
        {
            user = (arg.Entities as IList<User>)[0];
            Name = user.Name;
            Age = user.Age;
        }


        public string Name
        {
            get { return user.Name; }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new Exception("姓名不能为空");
                }
                user.Name = value;
                OnPropertyChanged("Name");
            }
        }


        public int Age
        {
            get { return user.Age; }
            set
            {
                if (value > 100)
                {
                    throw new Exception("年龄必须小与100");
                }
                user.Age = value;
                OnPropertyChanged("Age");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler pceh = PropertyChanged;
            if (pceh != null)
            {
                pceh(this,new PropertyChangedEventArgs(propertyName));
            }
        }
       
    }

UI效果图:

image

到此位置的源码下载为:SilverlightApplication20110618.zip

5:解决方案之使用ValidationSummary

使用ValidationSummary,需要我们引入程序集System.Windows.Controls.Data.Input,在UI前台,我们需要安置一个ValidationSummary:

image

接着,我们让前台的ValidationSummary的Errors赋值给VM。

    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            viewmodel = new MainPageVM(this.vs.Errors);
        }

        public MainPageVM viewmodel
        {
            get
            {
                return (MainPageVM)this.DataContext;
            }
            set
            {
                this.DataContext = value;
            }
        }

        private void btnSave_Click(object sender,RoutedEventArgs e)
        {

        }
    }

我们还需要为UI绑定一些Command,以便在需要验证输入的时候,让VM去判断是否有错误发生。一旦有错误发生,则为Errors添加错误项。

    public class MainPageVM : INotifyPropertyChanged
    {
        public MainPageVM(ObservableCollection<ValidationSummaryItem> errors)
        {
            m_errors = errors;
            Click = new ActionCommand(this.OnClick);
            serviceUser = new DomainServiceUser();
            serviceUser.Load<User>(serviceUser.GetAUserQuery(),null);
            //serviceUser.Load<User>(serviceUser.GetAUserQuery(),LoadBehavior.RefreshCurrent,null);
        }

        DomainServiceUser serviceUser;
        User user;
        ObservableCollection<ValidationSummaryItem> m_errors;

        void GetAUserCallBack(LoadOperation<User> arg)
        {
            user = (arg.Entities as IList<User>)[0];
            OnPropertyChanged("User");
        }

        public User User
        {
            get { return user; }
            set
            {
                user = value;
                OnPropertyChanged("User");
            }
        }

        public ICommand Click { get; private set; }

        public void OnClick(object arg)
        {
            m_errors.Clear();
            if (User.Age > 100)
            {
                m_errors.Add(new ValidationSummaryItem("年龄不能大雨100"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler pceh = PropertyChanged;
            if (pceh != null)
            {
                pceh(this,new PropertyChangedEventArgs(propertyName));
            }
        }

    }

最后的运行结果为:

image

备注:要让实体类在SL端支持EDIT,必须要让DomainService针对该实体类支持开放GUID接口。如下:

    [EnableClientAccess()]
    public class DomainServiceUser : DomainService
    {
        [Query]
        public IList<User> GetUsers()
        {
            return new List<User>()
            {
                new User() { Name = "huzhonghua",Age = 99 }
            };
        }

        public User GetAUser()
        {

            return new User() { Name = "luminji",Age = 98 };
        }

        [Delete]
        public void DeleteUser(User user)
        {
            throw new NotImplementedException();
        }

        [Insert]
        public void InsertUser(User user)
        {
            throw new NotImplementedException();
        }

        [Update]
        public void UpdateUser(User user)
        {
            throw new NotImplementedException();
        }

    }

本文源码下载:SilverlightApplication2001061902.zip

Charlie Calvert: Silverlight Simple Animation

Charlie Calvert: Silverlight Simple Animation

原作者:Charlie Calvert

原文地址: http://blogs.msdn.com/charlie/archive/2009/04/14/silverlight-simple-animation.aspx

This post is one of series on Silverlight. In this article the focus is on a technique that uses a timer to produce simple animations. I will follow this post with at least one additional article on Silverlight animation.

Silverlight has several built in techniques for animating controls. Many of these technologies are particularly useful for creating simple animations meant to decorate a web page with eye catching movement that draws the reader’s attention. In this post I will skip over these decorative technologies,and instead show how to create a simple animation using a technique similar to those used in many games.

这篇随笔是Silverlight系列随笔之一。其主要关注点在于一项使用计时器(Timer)来创建简单动画的技术。紧跟着这篇随笔,我会再额外发表至少一篇有关Silverlight动画的文章。

Silverlight有几种内置的技术使控件表现出动画效果。这些技术中大多数都对创建简单动画特别有用。这些动画意味着可以利用眼睛善于捕获运动的特点来修饰一个网页,从而引起读者的注意。在这篇随笔中,我将越过这些修饰性的技术,而展示一下如何使用与在很多游戏中使用的动画技术类似的技术来创建一个简单动画。

Though Silverlight is a web technology,the technique I will focus on is very similar to the same technology you would use in most standard programming languages such as C++ or Delphi. Though the animation technology I will focus on is often used in game programming,there are many different reasons why you might want to create this kind animation,particular in scientific programming,or code that attempts to illustrate complex numeric data.

尽管Silverlight是一项Web技术,但我将关注的技术与您在像C++或Dephi这样的标准编程语言中所使用的技术类似。虽然我将关注的动画技术通常被用于游戏编程,但您或许也有很多不同的理由想将其用于创建其他种类的动画,尤其是科学类的编程或者是试图演示复杂的数值数据的代码。

You will find that Silverlight makes the type of animation I want to focus on very simple. As such,it makes a good place to start an exploration of Silverlight animation. I want to emphasize,however,that there are other Silverlight techniques that use Storyboards and the DoubleAnimation and PointAnimation controls that might be more appropriate if you just want to add a bit of color to a web page. You can add a bit more complexity to those technologies by exploring key frames. See,for instance,the DoubleAnimationUsingKeyFrames control.

您会发现Silverlight使我想关注的那种动画类型实现起来很简单。因此,这是一个探索Silverlight动画的良好开端。然而,我想强调一下,如果您只是想对一个网页稍微润色一下,那么其他的使用Storyboard、DoubleAnimation和PointAnimation的Silverlight技术可能更符合您的需要。通过探索关键帧(Key Frame)的使用,您能够为这些技术再增加一点复杂度。您可以以DoubleAnimationUsingKeyFrames控制为例参考一下关键帧的使用。

In the example shown in this post I will create two simple “sprites” that I will animate by moving them smoothly and rapidly at an angle across a web page,as shown in figure 1. In figure 1,the blue Rectangle with the red border started its brief but illustrIoUs career near the upper right corner of the green field,and is moving down toward the bottom left corner. The purple and blue gradient image started at the upper left corner and is moving at an angle toward the bottom right of the green Canvas control.

在这篇随笔所展示的例子中,我将创建两个简单的“小精灵”,并演示一个让它们平滑而快速斜穿过一个网页的动画,正如图1所示,在图1中,带有红色边框的蓝色矩形从绿色场地的接近右上角的位置开始了它的短暂而又辉煌的行程,朝着左下角移动而下。而具有蓝紫渐变颜色的图片则从左上角开始,朝着绿色Canvas控件的右下角斜穿而过。

figure 1: Two simple sprites moving at angles across a green field.

Below you can see a live version of this application. Because the animation is quite brief,you will need to press the refresh button to see it in action.

图1:两个简单的小精灵斜穿过一块绿色场地

下面你能够看到这个程序的真实运行版。因为动画非常短暂,所以你会需要按下刷新按钮来看到它的运行。

The sprites in this example move smoothly and at a reasonable pace across the green surface. This is very important,as users frequently denigrate applications that have jerky or overly slow animations.

In the next post in this series I will show how to get more control over the sprites,and how to get them to “bounce” off the edges of a window so that they stay confined in a defined space,such as the green field shown here.

这个例子中的精灵们以一个合理的速度平滑地穿过绿色平面。这很重要,因为用户总是经常贬低那些拥有笨拙或过于缓慢的动画的应用程序。

在这个系列的下一篇随笔中,我将展示如何对这些精灵施加更多的控制,展示如何使它们弹离窗口的边界,以便它们可以始终被限制在一个预定义的空间之内,比如这里所显示的绿色区域。

Silverlight’s reliance on WPF frequently leaves developers with a choice between implementing their logic in XAML or in standard C# code,or in some combination of the two. Perhaps because my background is a C# developer,I tend to write only a minimal amount of XAML,and to implement most of my logic in C# code.

The XAML for this example is extremely simple:

Silverlight脱胎于WPF这一点,使开发者可以做出一种选择,是将他们的逻辑实现在XAML中还是在标准的C#代码中,或者是这两种形式的某种结合。或许因为我的背景是一名C#开发者,所以我倾向于只写少量的XAML代码,而以C#代码形式实现我的大部分逻辑。

这个例子的XAML代码非常简单:

 
 

Canvas> Grid> UserControl>

The code for the UserControl and the Grid is boilerplate Silverlight code produced by the IDE when any new Silverlight project is created. I’ve added only three items:

l A Canvas called myCanvas which has an event called StartTimer that is called when the Canvas is first loaded

l A blue and red Rectangle control that is 25 pixels square

l An Image control which is also 25 pixels square. It is referenced inside the program as myImage

UserControl和Grid的代码是当任何Silverlight项目被创建的时候都会由集成开发环境(IDE)生成的样板Silverlight代码。我只添加了三项:

l 一个被命名为myCanvas的Canvas,它有一个叫做StartTimer的事件处理方法,这个方法将在Canvas被第一次加载时调用。

l 一个25像素大小、红色边框、蓝色背景的正方形的矩形控件。

l 一个同样25像素大小的正方形的图片控件,它在程序中以myImage引用。

The XAML puts both controls in the upper left corner of the Canvas,which means that in design mode one will be hidden behind the other. The C# code I show in the next section moves the Rectangle off to the right of the Canvas,so that it has a unique location at run time.

XAML代码将两个控件都放到了Canvas的左上角,也就是说,在设计模式下,其中一个控件将被隐藏到另外一个的后面。下一小节我展示的C#代码将矩形控件移动到了Canvas的右边,以便它在运行时有一个独立的位置。

The Timer

Animations of the kind shown here are usually run off a timer which produces a kind of miniature application loop that is called at regular intervals and which acts as engine to drive the animation forward. The loop is started when the Canvas is loaded:

计时器(Timer)

这里展示的这种动画通常基于一个计时器(timer)运行,这个计时器以有规律的间隔调用一种小型程序循环,这种小型程序循环担当引擎来驱动动画向前播放。这个循环在Canvas被加载时启动:

private void StartTimer(object sender,RoutedEventArgs e)
{
    System.Windows.Threading.dispatcherTimer mydispatcherTimer =
new System.Windows.Threading.dispatcherTimer();
// Call the timer once every 10 milliseconds
mydispatcherTimer.Interval = new TimeSpan(0,10);
    mydispatcherTimer.Tick += new EventHandler(MoveShapes);
    mydispatcherTimer.Start();
}

This code is pulled nearly verbatim from the Silverlight documentation. It begins by creating a timer,then asks that the timer be fired once every ten milliseconds. A method called MoveShapes will be called whenever the timer is fired. Finally the code Starts the timer.

Here is the MoveShapes method,which is called by the timer once every ten milliseconds:

这段代码是从Silverlight文档中几乎一字不差地摘录下来的。它以创建一个计时器(timer)开始,随后让计时器每10毫秒触发一次。每次计时器被触发,一个叫做MoveShapes的方法就会被调用。

这是MoveShapes方法的代码,它每10毫秒就被计时器调用一次:

Double imageX = 0.0;
Double imageY = 0.0;
Double rectX = 275.0;
Double rectY = 1.0;
Double incValue = 1.0;
public void MoveShapes(object o,EventArgs sender)
{
    imageX += incValue;
    imageY += incValue;
    rectX -= incValue;
    rectY += incValue;            

    myRect.SetValue(Canvas.LeftProperty,rectX);
    myRect.SetValue(Canvas.TopProperty,rectY);

    myImage.SetValue(Canvas.LeftProperty,imageX);
    myImage.SetValue(Canvas.TopProperty,imageY);
}

This method is passed two parameters. The first is copy of the timer. You can use this object to disable or change the traits of the timer.

这个方法被传递进两个参数。第一个参数是计时器(timer)实例的引用。你可以使用这个对象来禁用计时器或者改变计时器的行为。

This code in the MoveShapes covers several lines,but its structure is very simple. I’ve declared values to track the current X and Y location of the upper left hand corner of the Image and Rectangle controls. Note that I initialize the rectX field to 275.0. It is this value that moves the Rectangle control over to he right of the Canvas at program start up,so that it is no longer hidden behind Image control. Needless to say,in the next article in this series I will create separate objects for each sprite. At this stage however,I’m focusing on showing you the basic animation techniques in the least possible amount of code.

MoveShapes方法的代码有好几行,但是它的结构却非常简单。我声明了一些值来跟踪图片控件和矩形控件左上角顶点的当前X和Y坐标值。注意,我将rectX字段的值初始化为275.0。这个值也正是在程序启动时矩形控件被移动到Canvas右边的初始位置,以便它不再被隐藏在图片控件之后。无需多说,在这个系列的下一篇文章,我将为每个精灵创建单独的对象。然而在现阶段,我将集中精力用尽可能少的代码向您展示基本的动画技术。

The last lines show how to call the SetValue method of the Rectangle and Image control in order to move the control across the surface of the Canvas. Silverlight provides us with a nice bonus feature here by automatically handling this transformation. In particular,it erases the original image of the control and then repaints it in the new location. In most computer languages,I would have had to manually write the code to erase the old image.

最后几行代码演示了如何调用矩形控件和图片控件的SetValue方法来移动控件穿过Canvas表面。在这里Silverlight通过自动处理这种转换为我们提供了一个很棒的优秀特性。尤其是,它擦除控件的原有图像然后再在新位置重新绘制图像。在大部分计算机编程语言中,我通常都不得不手工编写代码来擦除原有的图像。

Note that the MoveShapes method begins by incrementing or decrementing the fields that specify the location of the controls. This allows us to define how we move the controls across the surface of the Canvas. It is,the call to SetValue that actually transforms the location of the controls. The end result is a smooth animation of the controls across the surface of their container.

注意,MoveShapes方法通过增加或减小指定控件位置的字段的值来开始运行的。这允许我们定义怎样移动控件穿过Canvas表面。然而,是对SetValue这个方法的调用实际变换了控件的位置。结果就是产生了这些控件平滑地穿过他们容器表面的动画效果。

The best way to see this animation in action is to download the code and try it yourself. Remember that you need to first install the Silverlight integration for Visual Studio 2008,as described in the Get Started section of the Silverlight web site.

查看这段代码的实际动画效果最好的方式是您下载代码并亲自试试。记住,您首先需要安装Visual Studio 2008的Silverlight集成扩展,正如Silverlight官方网站的入门(Get Started)部分中所描述的一样。

Summary

The technique for animating controls that I’ve described in this article is very easy to use. Silverlight provides all the tools we need to set up simple animation without requiring any real effort on our part. As a result we can focus our energy on simply describing the path that we want our controls to follow. In particular,you need only:

l Set up a timer that calls a method you define at discreet intervals.

l Define the method called by the timer,and ensure that it contains logic for moving your controls.

总结

我在这边文章中所叙述的控件动画技术非常易于使用。Silverlight提供了所有我们需要的工具来创建简单动画,而不需要我们这边付出太多努力。因此我们可以把精力集中在简单明了地描述我们想让控件运动的路径。尤其是,你只需:

l 设置一个计时器,以谨慎设定的时间间隔调用您预先定义的一个方法。

l 实现被计时器调用的那个方法,确保它包含移动你的控件的逻辑。

As mentioned above,I’ll follow this post with at least one additional article that describes additional techniques for animating sprites. Those techniques require us to write a bit more code than that shown here,but at heart they are also very simple and easy to understand.

Download the SilverlightAnimatedTimer01.zip file containing the sample code from the LINQ Farm.

正如上文提到的,我会紧随着这篇随笔再发表至少一篇额外的文章描述使精灵产生动画效果的附加技术。这些技术相比这里展示的需要我们再多写一些代码。但凭心而论,它们也很简单并且易于理解。

可以从“LINQ Farm”上下载包含示例代码的SilverlightAnimatedTimer01.zip文件。

REF:http://www.cnblogs.com/Ricky81317/archive/2009/06/05/1497029.html

Silverlight 4 + RIA Services之商业应用系列----2 Updating&Validation

Silverlight 4 + RIA Services之商业应用系列----2 Updating&Validation

在你开始学习这篇文章之前,需要去看part1部分。

 part1: 如何使用RIA Services

part2: RIA Services更新和验证

part3:RIA Services数据新增

part4:皮肤的更改

part5:报表的展示

part6:Endpoint的设置

part7:如何使用RIA Service Class Library 

part8:url重写和界面友好

 

前面说到已经实现了数据显示在一个Datagrid中和搜索功能,为了能够有更好的用户体验,这里我会在客户端从服务器取数据时添加一个BusyIndicator控件。如下图:

 

只需要把一个BusyIndicator控件拖到页面,然后绑定IsBusy属性如下:

  <my1:BusyIndicator Grid.Row="1" Height="78" HorizontalAlignment="Left" Margin="257,82,0" x:Name="busyIndicator1" VerticalAlignment="Top" Width="177"

                           IsBusy="{Binding ElementName=restaurantDomainDataSource,Path=DomainContext.IsLoading}"/>

 

1.       编辑某条选中的记录,并更新到数据库。

使用RIA Service实现更新功能对我们来说简直是太容易了,首先我再增加一个Grid两列。

 

2.       然后在Data Sources中的Restaurant的箭头下选择Details,然后在把Restaurant拖拽到上面所示的那个Update Region中。

 

着我们需要添加一个Submit按钮用来作为更新数据的操作按钮,如下图:

 

Submit切换到代码,只需要简单的添加如下代码:

private void button1_Click(object sender,System.Windows.RoutedEventArgs e)

        {

            this.restaurantDomainDataSource.SubmitChanges();

        }

 

目前如果你的点击频率过快,RIA Service会出现异常,所以建议你也添加一个BusyIndicator

 

3.       Validation的自定义。

验证的添加,这个对于任何商业应用无疑都是很重要的。不然数据将会有很多垃圾数据。Silverlight 4Validation简直接近完美。可以为单个属性添加验证,也可以从一个实体级别添加验证,或者操作级别的。我给大家用上面的例子来给NameFax添加个自定义验证。

a.       Name的自定义验证:在Domain ServiceMetadata中为Name属性定义如下规则:

   [required(ErrorMessage="Please provide a Name")]

            public string Name { get; set; }

然后编译下,这时你再运行程序,如果你的Name字段为空则程序会警告你输入Name

 

  [RegularExpression(@"^http/://[a-zA-Z0-9/-/.]+/.[a-zA-Z]{2,3}(//S*)?$",

                    ErrorMessage = "Please use standard Url format")]

            public string HomePage { get; set; }

上面这个是如果你输入的HomePage不符合url规则则报错。

 

 

b.      通过使用CustomValidation方法来定义。比如:

 [CustomValidation(typeof(PlateValidationRules),

                  "IsPhoneValid")]

 

      public static ValidationResult IsPhoneValid(string Phone)

            {

                //Add Validation Rule here

             if ( )

             {

 

             }

              return ValidationResult.Success;

             }

 

下面的文章中会给大家介绍如何使用DataForm和自定义一个DataForm来新增一条记录,顺便把数据的导出也介绍下。

 

 

代码下载:

http://download.csdn.net/source/2274925 

Silverlight Navigation-Silverlight页面间自定义导航

关于Silverlight  Navigation导航我一直想写一篇文章总结一下在项目中实际应用. Navigation导航是关联一个应用程序中实现功能多样化最基本需求. 导航也可以详细分为应用程序导航[应用中多为Page之间],外部导航,集成浏览器导航等. Silverlight 发展今天版本4 当然也在这个方面做出很多努力. 从1.1 2.0 NavigationService到今天出现Frame控件,导航框架等. 逐渐丰富加强这方面运用. 本篇的目的自定义一个导航帮助类 实现Silverlight 中页面间导航操作. 先看看效果[稍微有点大]:

在项目中使用 新建三个测试页面 分别命名为:NvgTestPageOne /Two/Three.xaml,默认初始页TestPageone.xaml,可以从TestPageone跳转Two 跳转后可以通过Back按钮返回上一页. 当然各个页面间也支持直接跳转,整个流程如图:

实现步骤: 自定义导航帮助类-NavigationHelper

A:引用空间

 
 
  1. using System.Collections;  
  2. using System.Collections.Generic;  
  3. using System.Reflection;  

B:在NavigationHelper声明变量:

 
 
  1. //声明  
  2. private static Grid FrameGrid = new Grid();//用存储导航页面和实现操作  
  3. private static Dictionary<string, string> getFrameDic = new Dictionary<string, string>();//记录整个跳转流程 

C:从当前页面跳转到一个新页面:

 
 
  1. /// <summary>  
  2.          /// 跳转新页面  
  3.          /// </summary>  
  4.          public static void NavigationFrame(UserControl sendpage)  
  5.          {  
  6.              App getcurentapp = Application.Current as App;  
  7.              if (getcurentapp != null)  
  8.              {  
  9.                //保存老页面  
  10.                  Grid rootgrid=getcurentapp.RootVisual as Grid;  
  11.                  UserControl getoldpageCon = rootgrid.Children[0] as UserControl;  
  12.                //测试发现问题:SendPage.Name有可能为空. 换利用Type的属性值   
  13.                  //添加时注意键不能重复  
  14.                  bool isreply = false;  
  15.                  foreach (keyvaluePair<string, string> getkey in NavigationHelper.NavigationHelp.getFrameDic)  
  16.                  {  
  17.                      if (getkey.Key.Equals(sendpage.GetType().Name + "old"))  
  18.                      {  
  19.                          isreply = true;//已经存在  
  20.                      }  
  21.                  }  
  22.    
  23.                  if (!isreply)  
  24.                  {  
  25.                      NavigationHelp.getFrameDic.Add(sendpage.GetType().Name + "old", getoldpageCon.GetType().Name);  
  26.                  }  
  27.    
  28.                  //跳转新页面  
  29.                  rootgrid.Children.Clear();  
  30.                  rootgrid.Children.Insert(0, sendpage);  
  31.                  getcurentapp.RootVisual = rootgrid;  
  32.              }  
  33.          } 

这个方法参数就是要跳转到页面UserControl. 通过操作App.RootVisual中Grid. 把新页面作为子控件添加到Grid.Children集合中. 当然跳转后如果Back返回操作. 我们必须记录这个跳转流程在Dictionary<stringstring>中. 页面间记录识别模式如下:

D:返回到上一页

 
 
  1. /// <summary>  
  2.          /// 自动跳转到上一页 类似IE的历史记录  
  3.          /// </summary>  
  4.          public static void NavigationBackFrame(UserControl CurrentPage)  
  5.          {  
  6.              bool isexit = false;//是否存在上一页 或是判断是否是根目录  
  7.              string backpage = string.Empty;  
  8.              foreach (keyvaluePair<string,string> getkey in NavigationHelp.getFrameDic)  
  9.              {  
  10.                  if (getkey.Key.Equals(CurrentPage.GetType().Name+"old"))  
  11.                  {  
  12.                      isexit = true;//存在  
  13.                      backpage =getkey.Value;  
  14.                      //MessageBox.Show(backpage); 测试成功  
  15.                  }  
  16.              }  
  17.    
  18.              if (!string.IsNullOrEmpty(backpage))  
  19.              {  
  20.                  //返回上一页  
  21.                  UserControl getbackControl = NavigationHelp.NavigationGetControlByName(backpage);  
  22.                  if (getbackControl != null)  
  23.                  {  
  24.                      App getcurentapp = Application.Current as App;  
  25.                      Grid rootgrid = getcurentapp.RootVisual as Grid;  
  26.    
  27.                      //跳转  
  28.                      rootgrid.Children.Clear();  
  29.                      rootgrid.Children.Insert(0, getbackControl);  
  30.                      getcurentapp.RootVisual = rootgrid;  
  31.                  }  
  32.              }  
  33.              else 
  34.              {  
  35.                  //不存在或是已经是根目录  
  36.                  MessageBox.Show("当前已经是根目录!");  
  37.              }  
  38.          } 

BackFram如上方法参数是当前页Control 传入后在Dictionary中查找对应跳转流程上一页记录. 然后跳转. 其中获取对应各页Control利用Assembly发射原理.具体方法实现如下:

F:获得一个具体页面Control:

 
 
  1. /// <summary>  
  2.          /// 通过Control的名称利用反射获取 UserContol实例对象./  
  3.          /// </summary>  
  4.          public static UserControl NavigationGetControlByName(string controlname)  
  5.          {  
  6.              //获取当前Assembly  
  7.              UserControl getpageControl = null;  
  8.              Assembly getcurrentass = Assembly.GetExecutingAssembly();  
  9.    
  10.              foreach (Type gettype in getcurrentass.GetTypes())  
  11.              {  
  12.                  if (gettype.Name.Equals(controlname))  
  13.                  {  
  14.                      //存在该Control  
  15.                      getpageControl = Activator.CreateInstance(gettype) as UserControl;      
  16.                  }  
  17.              }  
  18.              return getpageControl;  
  19.          } 

G:调用方式

如从Testpageone跳转到TestpageTwo页面 如下:

 
 
  1. //调用导航帮助类下公开当行方法 跳转到TestpagetTwo  
  2. UserControl sendpageCon=NavigationHelper.NavigationHelp.NavigationGetControlByName("NvgTestPageTwo");  
  3. NavigationHelper.NavigationHelp.NavigationFrame(sendpageCon);  

如果从TestPageTwo页面返回到TestpageOne 调用如下:

 
 
  1.  //调用导航帮助类 返回记录上一页  
  2. UserControl currentControl = NavigationHelper.NavigationHelp.NavigationGetControlByName("NvgTestPageTwo");  
  3. NavigationHelper.NavigationHelp.NavigationBackFrame(currentControl);  

直接跳转就更简单 同方式一类似.

如上一个简单方式实现Silverlight页面间跳转自定义帮助类. 简便快捷.当然如上只是简单跳转.实际运用中涉及到页面间参数的传递,值状态保留等问题. 完全可以在这个基础之上加以扩展即可.关于更多的Silverlight Navigation实现方式 稍后会有介绍.

关于Silverlight Navigation项目源代码下载见附件。

Silverlight ValidatesOnException默认消息本地化

Silverlight ValidatesOnException默认消息本地化

在我的silverlight 4 MVVM应用程序中,我可以在运行时切换语言:

public void SetLanguage(string language)
{
    var culture = new CultureInfo(language);
    Thread.CurrentThread.CurrentUICulture = culture;
    Thread.CurrentThread.CurrentCulture = culture;
    // ...
}

对于输入,我只是在转换问题的情况下添加了“ValidatesOnException = true”并且它完成了工作.但默认的异常消息是在我的操作系统文化中,而不是在手动选择的消息中.

在exception message localization的这个帖子中,想法是改变CurrentCulture和CurrentUICulture,我做了.所以我有点卡住了.

我能做什么 ?

谢谢 :)

编辑:我试图在convertback方法中使用带有自定义异常的自定义转换器,以验证用户的输入.问题,转换方法中的异常不会被validatesOnException捕获,它会破坏应用程序.

编辑2:澄清 – >如果我有一个绑定到文本框的十进制属性,并在此文本框中输入“blabla”,我想看到有问题,我希望该消息在运行时区域设置而不是操作系统区域设置.
我不能在我的属性设置器中引发异常,因为我从未到达那里,默认转换器在此之前引发它自己的异常.

我希望它很清楚.如果我可以帮助你帮助我,请不要犹豫:)

解决方法

也许你不是在一开始就改变文化.

我建议您尝试在此链接的第一个答案中给出的方法:

Change culture of Silverlight application

关于SilverLight Tip 1 : Validation的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Charlie Calvert: Silverlight Simple Animation、Silverlight 4 + RIA Services之商业应用系列----2 Updating&Validation、Silverlight Navigation-Silverlight页面间自定义导航、Silverlight ValidatesOnException默认消息本地化等相关知识的信息别忘了在本站进行查找喔。

本文标签: