Submission and revocation of WPF data editing, and revocation of wpf editing

Source: Internet
Author: User

Submission and revocation of WPF data editing, and revocation of wpf editing

When you add or edit an item to a set (usually bound to a DataGrid or other ItemsControl controls), an attribute of the edit item is usually displayed on the editing page. After editing, the item is submitted, or we don't want to edit the data. At this time, we select cancel. The content of the data item has not changed.

When you bind a data item to the editing interface, you can define the Triggering Method for binding source updates. As shown in the following code, bind the Text attribute of TextBox to UpdateSourceTrigger = "Explicit ", in this case, you need to manually trigger data source updates.

   <TextBox.Text>        <Binding Path="Age" UpdateSourceTrigger="Explicit" >            <Binding.ValidationRules>                <validateRule:AgeRangeRule Min="21" Max="130" ValidationStep="ConvertedProposedValue"/>            </Binding.ValidationRules>        </Binding>    </TextBox.Text>

However, the disadvantage of the above method is that verification will not be triggered, which is terrible. We usually need data verification to visually feedback input errors and prompt users to enter standard content.

The solution officially provided is to use BindingGroup and enable the data class to implement the IEditableObject interface. This interface is implemented to provide data submission, revocation, and termination. The following is a definition of a data class. The actual data is stored by the Empolyee class, which is defined within the EmployeeEditAgent. The EmployeeEditAgent is equivalent to the Empolyee proxy and implements the IEditableObject interface, the EmployeeEditAgent defines the current data currentEmployee and backup data copyEmployee. When the BeginEdit method is called, the metadata is copied to currentEmployee. When the CancelEdit method is called, currentEmployee is copied to currentEmployee, data can be unedited through backup and recovery.

Public class EmployeeEditAgent: INotifyPropertyChanged, IEditableObject {[Serializable] class Employee {internal string Name {get; set;} internal int Age {get; set;} internal float Salary {get; set ;}} private Employee copyEmployee = null; private Employee currentEmployee = new Employee (); public string Name {get {return currentEmployee. name;} set {if (currentEmployee. name! = Value) {currentEmployee. Name = value; RaisePropertyChanged ("Name") ;}} public int Age {get {return currentEmployee. Age;} set {if (currentEmployee. Age! = Value) {currentEmployee. Age = value; RaisePropertyChanged ("Age") ;}} public float Salary {get {return currentEmployee. Salary;} set {if (currentEmployee. Salary! = Value) {currentEmployee. salary = value; RaisePropertyChanged ("Salary") ;}}# region Implementation of INotifyPropertyChanged public event inclupropertychanged = delegate {}; public void RaisePropertyChanged (string propertyname) {PropertyChanged (this, new Topology (propertyname) ;}# endregion # region Implementation of IEditableObject public void BeginEdit () {copyEmployee = DeepColone (currentEmployee);} public void EndEdit () {copyEmployee = null ;} public void CancelEdit () {currentEmployee = DeepColone (copyEmployee); RaisePropertyChanged ("") ;}# endregion private T DeepColone <T> (T t) {MemoryStream stream = new MemoryStream (); BinaryFormatter formatter = new BinaryFormatter (); formatter. serialize (stream, t); stream. position = 0; return (T) formatter. deserialize (stream );}}View Code

The data class is defined, and the BindingGroup class is also known. BindingGroup can update multiple binding sources at the same time. If a binding verification fails, the submission fails. To call the BindingGroup method, the IEditableObject interface bound to the source is called accordingly:

BindingGroup IEditableObject  
BeginEdit BeginEdit Start editing
CommitEdit EndEdit Submit for editing
CancelEdit CancelEdit Cancel editing

FrameworkElement or FrameworkContentElement both have the BindingGroup attribute. For the data class defined above, we usually bind the three attributes to the three TextBox respectively, the three controls are usually located in the same container (StackPanel or Grid setting Window). In this case, set the container's DataContext as the data source and create the BindingGroup on the container, at this time, the three TextBox will inherit the BindingGroup of the container, that is, when we set binding for any TextBox, the binding will be added to the BindingGroup of the container, so that the binding can be submitted at the same time, the following is the implementation of XAML. Note the code Annotations:

<Window x: Class = "WpfApplication2.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns: validateRule = "clr-namespace: ValidateRule" xmlns: wpfApplication2 = "clr-namespace: WpfApplication2" Title = "data verification Demo" Height = "217" Width = "332"> <Window. resources> <wpfApplication2: Employee Name = "MJ" Age = "25" Salary = "2500" x: Key = "employe E "> </wpfApplication2: Employee> <ControlTemplate x: Key =" validationTemplate "> <DockPanel> <AdornedElementPlaceholder/> <TextBlock Foreground =" Red "FontSize =" 20 ">! </TextBlock> </DockPanel> </ControlTemplate> <Style x: Key = "textBoxInError" TargetType = "{x: Type TextBox}"> <Style. triggers> <Trigger Property = "Validation. hasError "Value =" true "> <Setter Property =" ToolTip "Value =" {Binding RelativeSource = {x: Static RelativeSource. self}, Path = (Validation. errors) [0]. errorContent} "/> </Trigger> </Style. triggers> </Style> </Window. resources> <Window. bindingGroup> <BindingG Roup> </BindingGroup> <! -- The BindingGroup attribute of Window is instantiated here --> </Window. bindingGroup> <Grid. columnDefinitions> <ColumnDefinition Width = "118 *"/> </Grid. columnDefinitions> <Grid. rowDefinitions> <RowDefinition Height = "29"/> <RowDefinition Height = "110"/> <RowDefinition Height = "100 *"/> </Grid. rowDefinitions> <StackPanel Name = "stackPanel" Grid. row = "1" Margin = "5" Loaded = "stackPanel_Loaded"> <! -- <StackPanel. bindingGroup> </StackPanel. bindingGroup> --> <StackPanel Orientation = "Horizontal"> <Label Height = "30"> Name </Label> <TextBox Width = "70" Text = "{Binding Path = Name} "> </TextBox> </StackPanel> <StackPanel Orientation =" Horizontal "Margin =" 0, 5, 0, 0 "> <Label Height =" 30 "> age </Label> <TextBox Width =" 70 "Validation. errorTemplate = "{StaticResource validationTemplate}" Sty Le = "{StaticResource textBoxInError}"> <TextBox. Text> <Binding Path = "Age" UpdateSourceTrigger = "PropertyChanged"> <! -- BindingGroup --> <Binding. validationRules> <validateRule: AgeRangeRule Min = "21" Max = "130" ValidationStep = "RawProposedValue"/> </Binding. validationRules> </Binding> </TextBox. text> </TextBox> <TextBlock TextWrapping = "Wrap" Text = "{Binding Path = Age}" Width = "98"/> </StackPanel> <StackPanel Orientation = "Horizontal "Margin =" 0, 5, 0, 0 "> <Label Height =" 30 "> Salary </Label> <TextBox Width =" 70 "Text =" {Binding Path = Salary} "> </TextBox> </ stackPanel> </StackPanel> <Label Content = "employee information" FontSize = "15"/> <Button Content = "Submit" HorizontalAlignment = "Left" Height = "22" Margin = "54,10, 0, 0 "Grid. row = "2" VerticalAlignment = "Top" Width = "76" Click = "Button_Click"/> <Button Content = "cancel" HorizontalAlignment = "Left" Height = "22" Margin = "165, 10, 0, 0 "Grid. row = "2" VerticalAlignment = "Top" Width = "76" Click = "Button_Click_1"/> </Grid> </Window>

The following is the implementation of the Code. Pay attention to the call of the three BindingGroup Methods BeginEdit, CommitEdit, and CancelEdit:

Public partial class MainWindow: Window {public MainWindow () {InitializeComponent (); // stackPanel. dataContext = new EmployeeEditAgent () {Name = "Mj", Age = 35, Salary = 2500}; this. dataContext = new EmployeeEditAgent () {Name = "Mj", Age = 35, Salary = 2500};} private void stackPanel_Loaded (object sender, RoutedEventArgs e) {// stackPanel. bindingGroup. beginEdit (); this. bindingGroup. beginEdit (); // start to edit the transaction} private void Button_Click (object sender, RoutedEventArgs e) {// if (stackPanel. bindingGroup. commitEdit () // {// MessageBox. show ("success"); // else // {// MessageBox. show (""); //} if (this. bindingGroup. commitEdit () // submit and edit {MessageBox. show ("success");} else {MessageBox. show ("failed") ;}} private void Button_Click_1 (object sender, RoutedEventArgs e) {this. bindingGroup. cancelEdit (); // cancel editing }}View Code

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.