/// <summary>
        /// Serializes a PesistentVM to disk, in a XML file format
        /// </summary>
        /// <param name="fileName">The file name of the ViewModel to save</param>
        /// <param name="vmToPersist">The actual serializable ViewModel</param>
        /// <returns>True if the save operation succeeds</returns>
        public static Boolean PersistViewModel(String fileName, PesistentVM vmToPersist)
        {
            try
            {
                FileInfo file = new FileInfo(fileName);
                if (!file.Extension.Equals(".xml"))
                    throw new NotSupportedException(
                        String.Format("The file name {0} you picked is not supported\r\n\r\nOnly .xml files are valid",
                        file.Name));

                if (vmToPersist == null)
                    throw new NotSupportedException("The ViewModel is null");

                
                //write the file to disk
                XmlSerializer serializer = new XmlSerializer(typeof(PesistentVM));

                using (TextWriter writer = new StreamWriter(file.FullName))
                {
                    serializer.Serialize(writer, vmToPersist);
                }
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Serializes a PesistentVM to disk, in a XML file format
        /// </summary>
        /// <param name="fileName">The file name of the ViewModel to save</param>
        /// <param name="vmToPersist">The actual serializable ViewModel</param>
        /// <returns>True if the save operation succeeds</returns>
        public static Boolean PersistViewModel(String fileName, PesistentVM vmToPersist)
        {
            try
            {
                FileInfo file = new FileInfo(fileName);
                if (!file.Extension.Equals(".xml"))
                {
                    throw new NotSupportedException(
                              String.Format("The file name {0} you picked is not supported\r\n\r\nOnly .xml files are valid",
                                            file.Name));
                }

                if (vmToPersist == null)
                {
                    throw new NotSupportedException("The ViewModel is null");
                }


                //write the file to disk
                XmlSerializer serializer = new XmlSerializer(typeof(PesistentVM));

                using (TextWriter writer = new StreamWriter(file.FullName))
                {
                    serializer.Serialize(writer, vmToPersist);
                }
                return(true);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Beispiel #3
0
        /// <summary>
        /// DeSerializes an XML file into a PesistentVM
        /// (if the xml is of the correct formatting)
        /// </summary>
        /// <param name="fileName">The file name of the ViewModel to open</param>
        /// <returns>The XML read PesistentVM, or null if it can't be read</returns>
        public static PesistentVM HydratePersistedViewModel(String fileName)
        {
            try
            {
                FileInfo file = new FileInfo(fileName);
                if (!file.Extension.Equals(".xml"))
                {
                    throw new NotSupportedException(
                              String.Format("The file name {0} you picked is not supported\r\n\r\nOnly .xml files are valid",
                                            file.Name));
                }

                //read the file from disk
                XmlSerializer serializer = new XmlSerializer(typeof(PesistentVM));
                serializer.UnknownNode      += Serializer_UnknownNode;
                serializer.UnknownAttribute += Serializer_UnknownAttribute;
                PesistentVM vmToHydrate = null;

                using (FileStream fs = new FileStream(file.FullName, FileMode.Open))
                {
                    vmToHydrate = (PesistentVM)serializer.Deserialize(fs);
                }
                return(vmToHydrate);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Beispiel #4
0
        /// <summary>
        /// Creates a new InMemoryViewModel by reading the persisted XML file from disk
        /// </summary>
        private void HydrateViewModelFromXml()
        {
            //Ask the user where they want to open the file from, and open it
            try
            {
                openFileService.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
                openFileService.FileName         = String.Empty;
                openFileService.Filter           = "Xml files (*.xml)|*.xml";
                bool?result = openFileService.ShowDialog(null);

                if (result.HasValue && result.Value)
                {
                    //open to XML
                    PesistentVM pesistentVM =
                        ViewModelPersistence.HydratePersistedViewModel(openFileService.FileName);
                    //check we got something, and recreate the full weight InMemoryViewModel from
                    //the lighter weight XML read PesistentVM
                    if (pesistentVM != null)
                    {
                        CurrentVM = new InMemoryViewModel();

                        //Start out with PropertiesViewModel shown
                        PropertiesViewModel propertiesViewModel =
                            new PropertiesViewModel();
                        propertiesViewModel.IsCloseable = false;
                        CurrentVM.PropertiesVM          = propertiesViewModel;
                        //and now read in other data
                        CurrentVM.ViewModelName        = pesistentVM.VMName;
                        CurrentVM.CurrentViewModelType = pesistentVM.VMType;
                        CurrentVM.ViewModelNamespace   = pesistentVM.VMNamespace;
                        //and add in the individual properties
                        foreach (var prop in pesistentVM.VMProperties)
                        {
                            CurrentVM.PropertiesVM.PropertyVMs.Add(new
                                                                   SinglePropertyViewModel
                            {
                                PropertyType   = prop.PropertyType,
                                PropName       = prop.PropName,
                                UseDataWrapper = prop.UseDataWrapper
                            });
                        }

                        HasContent = true;
                    }
                    else
                    {
                        messageBoxService.ShowError(String.Format("Could not open the ViewModel {0}",
                                                                  openFileService.FileName));
                    }
                }
            }
            catch (Exception ex)
            {
                messageBoxService.ShowError("An error occurred trying to Opening the ViewModel\r\n" +
                                            ex.Message);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Creates and returns a single generated code String which has both parts
        /// of the partial class, wcich can then be sent to the compilation phase
        /// as a single file. The single code string is generated based on the vmToPersist
        /// parameter
        /// </summary>
        private static String CreateAllCodeParts(PesistentVM vmToPersist)
        {
            //The order is important, do not change the order here
            //otherwise it will not work
            String autoPart   = CreateAutoGeneratedPart(vmToPersist, false);
            String customPart = CreateCustomPart(vmToPersist, false);

            StringBuilder sb = new StringBuilder(1000);

            sb.Append(autoPart);
            sb.Append(customPart);
            sb.AppendLine("}");

            return(sb.ToString());
        }
Beispiel #6
0
        /// <summary>
        /// Creates the ViewModel code in C# format
        /// </summary>
        /// <param name="fileName">The file name of the ViewModel to save</param>
        /// <param name="vmToPersist">The actual serializable ViewModel</param>
        /// <returns>True if the save operation succeeds</returns>
        public static Boolean CreateViewModelCode(String fileName, PesistentVM vmToPersist)
        {
            try
            {
                if (vmToPersist == null)
                {
                    throw new NotSupportedException("The ViewModel is null");
                }


                FileInfo file    = new FileInfo(fileName);
                String   allCode = CreateAllCodeParts(vmToPersist);
                Tuple <Boolean, String> compilationSucceeded = CompileGeneratedCode(allCode);


                //check for .g.cs
                String justFilePart = StripFileName(fileName);

                //Write the Auto generated file part
                String autoGeneratedFileName = String.Format("{0}.g.cs", justFilePart);
                String autoGeneratedFilePath = Path.Combine(file.Directory.FullName, autoGeneratedFileName);
                String autoGenPartContents   = CreateAutoGeneratedPart(vmToPersist, true);

                //No need to carry on if user says don't generate 1st part
                if (!SaveGeneratedCode(compilationSucceeded.First, compilationSucceeded.Second,
                                       autoGeneratedFileName, autoGenPartContents))
                {
                    return(false);
                }


                //Write the Custom file part
                String customFileName     = String.Format("{0}.cs", justFilePart);
                String customFilePath     = Path.Combine(file.Directory.FullName, customFileName);
                String customPartContents = CreateCustomPart(vmToPersist, true);
                return(SaveGeneratedCode(compilationSucceeded.First, compilationSucceeded.Second,
                                         customFileName, customPartContents));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Creates the ViewModel code in C# format
        /// </summary>
        /// <param name="fileName">The file name of the ViewModel to save</param>
        /// <param name="vmToPersist">The actual serializable ViewModel</param>
        /// <returns>True if the save operation succeeds</returns>
        public static Boolean CreateViewModelCode(String fileName, PesistentVM vmToPersist)
        {
            try
            {
                if (vmToPersist == null)
                    throw new NotSupportedException("The ViewModel is null");

                
                FileInfo file = new FileInfo(fileName);
                String allCode = CreateAllCodeParts(vmToPersist);
                Tuple<Boolean,String> compilationSucceeded = CompileGeneratedCode(allCode);

                
                //check for .g.cs
                String justFilePart = StripFileName(fileName);

                //Write the Auto generated file part
                String autoGeneratedFileName = String.Format("{0}.g.cs", justFilePart);
                String autoGeneratedFilePath = Path.Combine(file.Directory.FullName, autoGeneratedFileName);
                String autoGenPartContents = CreateAutoGeneratedPart(vmToPersist, true);
  
                //No need to carry on if user says don't generate 1st part
                if (!SaveGeneratedCode(compilationSucceeded.First,compilationSucceeded.Second,
                    autoGeneratedFileName, autoGenPartContents))
                    return false;


                //Write the Custom file part
                String customFileName = String.Format("{0}.cs", justFilePart);
                String customFilePath = Path.Combine(file.Directory.FullName, customFileName);
                String customPartContents = CreateCustomPart(vmToPersist, true);
                return SaveGeneratedCode(compilationSucceeded.First, compilationSucceeded.Second, 
                    customFileName, customPartContents);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Creates and returns an custom generated part String, based on the vmToPersist
        /// parameter. The returned string will form tne auto generated part (.cs)
        /// </summary>
        private static String CreateCustomPart(PesistentVM vmToPersist, Boolean shouldEmit)
        {
            StringBuilder sb = new StringBuilder(1000);

            //write out namespaces
            #region Namespaces
            if (shouldEmit)
            {
                sb.AppendLine("using System;");
                sb.AppendLine("using System.Collections.Generic;");
                sb.AppendLine("using System.Linq;");
                sb.AppendLine("using System.ComponentModel;");
                sb.AppendLine("using System.Collections.ObjectModel;");
                sb.AppendLine("using System.Windows.Data;");
                sb.AppendLine("using System.Collections.Specialized;");

                //write out referenced assemblies Using statements
                List<String> refAssUsingStments =
                    ReferencedAssembliesHelper.GetReferencedAssembliesUsingStatements();
                if (refAssUsingStments.Count > 0)
                {
                    sb.AppendLine("//Referenced assemblies");
                    foreach (String usingStmnt in refAssUsingStments)
                    {
                        sb.AppendLine(usingStmnt);
                    }
                    sb.AppendLine();
                }
                sb.AppendLine("using Cinch;");
                sb.AppendLine();

                sb.AppendLine(String.Format("namespace {0}", vmToPersist.VMNamespace));
                sb.AppendLine("{");
            }
            #endregion

            //Write out data
            #region Data
            sb.AppendLine("\t/// <summary>");
            sb.AppendLine("\t///You may edit this code by hand, but there is DataWrapper code");
            sb.AppendLine("\t///and some boiler plate code provided here, to help you on your way.");
            sb.AppendLine("\t///A lot of which is actually quite useful, and a lot of thought has been");
            sb.AppendLine("\t///put into, what code to place in which file parts, and this custom part");
            sb.AppendLine("\t///does have some excellent starting code, so use it as you wish.");
            sb.AppendLine("\t///");
            sb.AppendLine("\t///But please note : One area that will need to be examined closely if you decide to introduce");
            sb.AppendLine("\t///New DataWrapper<T> properties in this part, is the IsValid override");
            sb.AppendLine("\t///Which will need to include the dataWrappers something like:");
            sb.AppendLine("\t///<pre>");
            sb.AppendLine("\t///       return base.IsValid &&");
            sb.AppendLine("\t///          DataWrapperHelper.AllValid(cachedListOfDataWrappers);");
            sb.AppendLine("\t///</pre>");
            sb.AppendLine("\t/// </summary>");


            sb.AppendLine(String.Format("\tpublic partial class {0}", vmToPersist.VMName));
            sb.AppendLine("\t{");


            //write fields
            var propsWithWrappers = vmToPersist.VMProperties.Where(x => x.UseDataWrapper == true);
            if (propsWithWrappers.Count() > 0)
            {
                sb.AppendLine("\t\t#region Data");
                sb.AppendLine("\t\tprivate IEnumerable<DataWrapperBase> cachedListOfDataWrappers;");
                sb.AppendLine("\t\tprivate ViewMode currentViewMode = ViewMode.AddMode;");
                sb.AppendLine("\t\t//Example rule declaration : YOU WILL NEED TO DO THIS BIT");
                sb.AppendLine("\t\t//private static SimpleRule quantityRule;");
                sb.AppendLine("\t\t#endregion");
            }
            sb.AppendLine();
            #endregion

            //Ctor
            #region Ctor
            sb.AppendLine("\t\t#region Ctor");
            sb.AppendLine(String.Format("\t\tpublic {0}()", vmToPersist.VMName));
            sb.AppendLine("\t\t{");

            //write out wrappers if they are needed
            if (propsWithWrappers.Count() > 0)
            {
                sb.AppendLine("\t\t\t#region Create DataWrappers");
                foreach (var propWithWrapper in propsWithWrappers)
                    sb.AppendLine(propWithWrapper.ConstructorDeclaration);

                sb.AppendLine("\t\t\t//fetch list of all DataWrappers, so they can be used again later without the");
                sb.AppendLine("\t\t\t//need for reflection");
                sb.AppendLine("\t\t\tcachedListOfDataWrappers =");
                sb.AppendLine(String.Format(
                    "\t\t\t    DataWrapperHelper.GetWrapperProperties<{0}>(this);",vmToPersist.VMName));
                sb.AppendLine("\t\t\t#endregion");


            }

            sb.AppendLine("\t\t\t#endregion");

            //write out auto generated part callbacks
            sb.AppendLine();
            sb.AppendLine("\t\t\t#region Create Auto Generated Property Callbacks");
            sb.AppendLine("\t\t\t//Create callbacks for auto generated properties in auto generated partial class part");
            sb.AppendLine("\t\t\t//Which allows this part to know when a property in the generated part changes");
            foreach (var prop in vmToPersist.VMProperties)
            {
                sb.AppendLine(prop.CustomPartCtorCallBack);
            }


            //write out example validation, if this ViewModel type supports them
            if (vmToPersist.VMType != ViewModelType.Standard)
            {
                sb.AppendLine();
                sb.AppendLine("\t\t\t//    #region TODO : You WILL need to create YOUR OWN validation rules");
                sb.AppendLine("\t\t\t//    //Here is an example of how to create a validation rule");
                sb.AppendLine("\t\t\t//    //you can use this as a guide to create your own validation rules");
                sb.AppendLine("\t\t\t//    quantity.AddRule(quantityRule);");
                sb.AppendLine("\t\t\t//    #endregion");
            }

            sb.AppendLine("\t\t}");



            //write out static Constructor
            sb.AppendLine();
            sb.AppendLine(String.Format("\t\tstatic {0}()", vmToPersist.VMName));
            sb.AppendLine("\t\t{");
            sb.AppendLine("\t\t\t//quantityRule = new SimpleRule(\"DataValue\", \"Quantity can not be < 0\",");
            sb.AppendLine("\t\t\t//          (Object domainObject)=>");
            sb.AppendLine("\t\t\t//          {");
            sb.AppendLine("\t\t\t//              DataWrapper<Int32> obj = (DataWrapper<Int32>)domainObject;");
            sb.AppendLine("\t\t\t//              return obj.DataValue <= 0;");
            sb.AppendLine("\t\t\t//          });");
            sb.AppendLine("\t\t}");

            sb.AppendLine("\t\t#endregion");
            #endregion

            //Write out actual auto generated property changed callback stubs
            #region Property Changed Stubs
            sb.AppendLine();
            sb.AppendLine("\t\t#region Auto Generated Property Changed CallBacks");
            sb.AppendLine("\t\t//Callbacks which are called whenever an auto generated property in auto generated partial class part changes");
            sb.AppendLine("\t\t//Which allows this part to know when a property in the generated part changes");
            foreach (var prop in vmToPersist.VMProperties)
            {
                sb.AppendLine(prop.CustomPartActualCallBack);
            }

            sb.AppendLine("\t\t#endregion");
            #endregion

            //region ViewMode property
            #region ViewMode property (which allows all DataWrappers to be put into a specific ViewMode state)
            if (propsWithWrappers.Count() > 0)
            {
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// The current ViewMode, when changed will loop");
                sb.AppendLine("\t\t/// through all nested DataWrapper objects and change");
                sb.AppendLine("\t\t/// their state also");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tstatic PropertyChangedEventArgs currentViewModeChangeArgs =");
                sb.AppendLine(String.Format(
                    "\t\t    ObservableHelper.CreateArgs<{0}>(x => x.CurrentViewMode);", 
                    vmToPersist.VMName));
                sb.AppendLine();
                sb.AppendLine("\t\tpublic ViewMode CurrentViewMode");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    get { return currentViewMode; }");
                sb.AppendLine("\t\t    set");
                sb.AppendLine("\t\t    {");
                sb.AppendLine("\t\t        currentViewMode = value;");
                sb.AppendLine("\t\t        //Now change all the cachedListOfDataWrappers");
                sb.AppendLine("\t\t        //Which sets all the Cinch.DataWrapper<T>s to the correct IsEditable");
                sb.AppendLine("\t\t        //state based on the new ViewMode applied to the ViewModel");
                sb.AppendLine("\t\t        //we can use the Cinch.DataWrapperHelper class for this");
                sb.AppendLine("\t\t        DataWrapperHelper.SetMode(");
                sb.AppendLine("\t\t            cachedListOfDataWrappers,");
                sb.AppendLine("\t\t            currentViewMode);");
                sb.AppendLine();
                sb.AppendLine("\t\t        NotifyPropertyChanged(currentViewModeChangeArgs);");
                sb.AppendLine("\t\t    }");
                sb.AppendLine("\t\t}");
            }
            #endregion


            //Overrides (IsValid)
            #region Overrides
            if (vmToPersist.VMType != ViewModelType.Standard)
            {
                sb.AppendLine();
                sb.AppendLine("\t\t#region Overrides");
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// Override hook which allows us to also put any child ");
                sb.AppendLine("\t\t/// EditableValidatingObject objects IsValid state into");
                sb.AppendLine("\t\t/// a combined IsValid state for the whole ViewModel,");
                sb.AppendLine("\t\t/// should you need to do so");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tpublic override bool IsValid");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    get");
                sb.AppendLine("\t\t    {");
                if (propsWithWrappers.Count() > 0)
                {
                    sb.AppendLine("\t\t       //return base.IsValid and use DataWrapperHelper, as you are");
                    sb.AppendLine("\t\t       //using DataWrappers");
                    sb.AppendLine("\t\t       return base.IsValid &&");
                    sb.AppendLine("\t\t          DataWrapperHelper.AllValid(cachedListOfDataWrappers);");
                }
                else
                {
                    sb.AppendLine("\t\t       //simply return base.IsValid as you are not");
                    sb.AppendLine("\t\t       //using DataWrappers");
                    sb.AppendLine("\t\t       return base.IsValid;");
                }
                sb.AppendLine("\t\t    }");
                sb.AppendLine("\t\t}");
                sb.AppendLine("\t\t#endregion");
            }
            #endregion

            sb.AppendLine("\t}");
            if (shouldEmit)
                sb.AppendLine("}");

            return sb.ToString();
        }
        /// <summary>
        /// Creates and returns an auto generated part String, based on the vmToPersist
        /// parameter. The returned string will form tne auto generated part (.g.cs)
        /// </summary>
        private static String CreateAutoGeneratedPart(PesistentVM vmToPersist, Boolean shouldEmit)
        {
            StringBuilder sb = new StringBuilder(1000);

            //Write out namespaces
            #region Namespaces
            sb.AppendLine("using System;");
            sb.AppendLine("using System.Collections.Generic;");
            sb.AppendLine("using System.Linq;");
            sb.AppendLine("using System.ComponentModel;");
            sb.AppendLine("using System.Collections.ObjectModel;");
            sb.AppendLine("using System.Windows.Data;");
            sb.AppendLine("using System.Collections.Specialized;");

            //write out referenced assemblies Using statements
            List<String> refAssUsingStments =
                ReferencedAssembliesHelper.GetReferencedAssembliesUsingStatements();
            if (refAssUsingStments.Count > 0)
            {
                sb.AppendLine();
                sb.AppendLine("//Referenced assemblies");
                foreach (String usingStmnt in refAssUsingStments)
                {
                    sb.AppendLine(usingStmnt);
                }
                sb.AppendLine();
            }
            sb.AppendLine("using Cinch;");
            sb.AppendLine();
            #endregion

            #region Class code
            sb.AppendLine(String.Format("namespace {0}", vmToPersist.VMNamespace));
            sb.AppendLine("{");

            sb.AppendLine("\t/// <summary>");
            sb.AppendLine("\t///NOTE : This class was auto generated by a tool");
            sb.AppendLine("\t///Edit this code at your peril!!!!!!");
            sb.AppendLine("\t/// </summary>");
            
            sb.AppendLine(String.Format("\tpublic partial class {0} : Cinch.{1}",
                vmToPersist.VMName, vmToPersist.InheritenceVMType.ToString()));
            sb.AppendLine("\t{");

            //write Data
            #region Data
            sb.AppendLine("\t\t#region Data");
            foreach (var prop in vmToPersist.VMProperties)
                sb.AppendLine(prop.FieldDeclaration);
            sb.AppendLine("\t\t//callbacks to allow auto generated part to notify custom part, when property changes");
            sb.AppendLine("\t\tprivate Dictionary<String, Action> autoPartPropertyCallBacks = new Dictionary<String, Action>();");
            sb.AppendLine("\t\t#endregion");
            sb.AppendLine("\r\n");
            #endregion

            //write get/set declarations
            #region Props
            sb.AppendLine("\t\t#region Public Properties");
            foreach (var prop in vmToPersist.VMProperties)
                sb.AppendLine(prop.PropGetSet);
            sb.AppendLine("\t\t#endregion");
            #endregion

            #region EditableValidatingObject overrides

            var propsWithWrappers = 
                vmToPersist.VMProperties.Where(x => x.UseDataWrapper == true);


            //EditableValidatingObject overrides
            if (vmToPersist.VMType == ViewModelType.ValidatingAndEditable
                && propsWithWrappers.Count() > 0)
            {
                sb.AppendLine("\t\t#region EditableValidatingObject overrides");

                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// Override hook which allows us to also put any child");
                sb.AppendLine("\t\t/// EditableValidatingObject objects into the BeginEdit state");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tprotected override void OnBeginEdit()");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    base.OnBeginEdit();");
                sb.AppendLine("\t\t    //Now walk the list of properties in the ViewModel");
                sb.AppendLine("\t\t    //and call BeginEdit() on all Cinch.DataWrapper<T>s.");
                sb.AppendLine("\t\t    //we can use the Cinch.DataWrapperHelper class for this");
                sb.AppendLine("\t\t    DataWrapperHelper.SetBeginEdit(cachedListOfDataWrappers);");
                sb.AppendLine("\t\t}");
                sb.AppendLine();
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// Override hook which allows us to also put any child");
                sb.AppendLine("\t\t/// EditableValidatingObject objects into the EndEdit state");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tprotected override void OnEndEdit()");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    base.OnEndEdit();");
                sb.AppendLine("\t\t    //Now walk the list of properties in the ViewModel");
                sb.AppendLine("\t\t    //and call CancelEdit() on all Cinch.DataWrapper<T>s.");
                sb.AppendLine("\t\t    //we can use the Cinch.DataWrapperHelper class for this");
                sb.AppendLine("\t\t    DataWrapperHelper.SetEndEdit(cachedListOfDataWrappers);");
                sb.AppendLine("\t\t}");
                sb.AppendLine();
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// Override hook which allows us to also put any child ");
                sb.AppendLine("\t\t/// EditableValidatingObject objects into the CancelEdit state");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tprotected override void OnCancelEdit()");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    base.OnCancelEdit();");
                sb.AppendLine("\t\t    //Now walk the list of properties in the ViewModel");
                sb.AppendLine("\t\t    //and call CancelEdit() on all Cinch.DataWrapper<T>s.");
                sb.AppendLine("\t\t    //we can use the Cinch.DataWrapperHelper class for this");
                sb.AppendLine("\t\t    DataWrapperHelper.SetCancelEdit(cachedListOfDataWrappers);");
                sb.AppendLine("\t\t}");
                sb.AppendLine("\t\t#endregion");
            }
            #endregion


            #endregion

            sb.AppendLine("\t}");

            if (shouldEmit)
                sb.AppendLine("}");

            return sb.ToString();
        }
        /// <summary>
        /// Creates and returns a single generated code String which has both parts
        /// of the partial class, wcich can then be sent to the compilation phase
        /// as a single file. The single code string is generated based on the vmToPersist
        /// parameter
        /// </summary>
        private static String CreateAllCodeParts(PesistentVM vmToPersist)
        {
            //The order is important, do not change the order here
            //otherwise it will not work
            String autoPart = CreateAutoGeneratedPart(vmToPersist, false);
            String customPart = CreateCustomPart(vmToPersist, false);

            StringBuilder sb = new StringBuilder(1000);
            sb.Append(autoPart);
            sb.Append(customPart);
            sb.AppendLine("}");

            return sb.ToString();

        }
        /// <summary>
        /// Saves the current ViewModel as an XML file or generates C# code for the
        /// current ViewModel
        /// </summary>
        /// <param name="filter">The save file filter to use</param>
        /// <param name="operation">The SaveOrGenerate operation to use</param>
        private Tuple <Boolean, String> SaveOrGenerateOperation(String filter, SaveOrGenerate operation)
        {
            if (!IsValid)
            {
                messageBoxService.ShowError("The current ViewModel is InValid\r\nPlease fix it then retry");
                return(null);
            }
            else
            {
                //Ask the user where they want to save the file, and save it
                try
                {
                    saveFileService.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
                    saveFileService.FileName         = String.Empty;
                    saveFileService.Filter           = filter;
                    saveFileService.OverwritePrompt  = true;
                    bool?result = saveFileService.ShowDialog(null);

                    if (result.HasValue && result.Value)
                    {
                        //Create a Persistence ViewModel based on the current In Memory ViewModel
                        PesistentVM pesistentVM = new PesistentVM();
                        pesistentVM.VMName      = ViewModelName;
                        pesistentVM.VMType      = CurrentViewModelType;
                        pesistentVM.VMNamespace = ViewModelNamespace;

                        foreach (SinglePropertyViewModel propVM in propertiesViewModel.PropertyVMs)
                        {
                            pesistentVM.VMProperties.Add(new
                                                         PesistentVMSingleProperty
                            {
                                PropertyType        = propVM.PropertyType,
                                PropName            = propVM.PropName,
                                UseDataWrapper      = propVM.UseDataWrapper,
                                ParentViewModelName = ViewModelName
                            });
                        }


                        bool success = false;

                        FileInfo file = new FileInfo(saveFileService.FileName);

                        //decide what file needs saving/generating
                        switch (operation)
                        {
                        case SaveOrGenerate.Save:
                            //save to XML
                            success = ViewModelPersistence.PersistViewModel(
                                saveFileService.FileName, pesistentVM);
                            ShowSaveOrGenMessage(success, file.Name, SaveOrGenerate.Save);
                            return(TupleHelper.New(success, saveFileService.FileName));

                        case SaveOrGenerate.Generate:
                            //generate code
                            success = ViewModelPersistence.CreateViewModelCode(
                                saveFileService.FileName, pesistentVM);
                            ShowSaveOrGenMessage(success, file.Name, SaveOrGenerate.Generate);
                            return(TupleHelper.New(success, saveFileService.FileName));
                        }
                    }
                }
                catch (Exception ex)
                {
                    messageBoxService.ShowError(
                        String.Format("An error occurred trying to {0} the ViewModel\r\n{1}",
                                      operation.ToString(), ex.Message));
                    return(null);
                }
                return(null);
            }
        }
Beispiel #12
0
        /// <summary>
        /// Creates and returns an custom generated part String, based on the vmToPersist
        /// parameter. The returned string will form tne auto generated part (.cs)
        /// </summary>
        private static String CreateCustomPart(PesistentVM vmToPersist, Boolean shouldEmit)
        {
            StringBuilder sb = new StringBuilder(1000);

            //write out namespaces
            #region Namespaces
            if (shouldEmit)
            {
                sb.AppendLine("using System;");
                sb.AppendLine("using System.Collections.Generic;");
                sb.AppendLine("using System.Linq;");
                sb.AppendLine("using System.ComponentModel;");
                sb.AppendLine("using System.Collections.ObjectModel;");
                sb.AppendLine("using System.Windows.Data;");
                sb.AppendLine("using System.Collections.Specialized;");

                //write out referenced assemblies Using statements
                List <String> refAssUsingStments =
                    ReferencedAssembliesHelper.GetReferencedAssembliesUsingStatements();
                if (refAssUsingStments.Count > 0)
                {
                    sb.AppendLine("//Referenced assemblies");
                    foreach (String usingStmnt in refAssUsingStments)
                    {
                        sb.AppendLine(usingStmnt);
                    }
                    sb.AppendLine();
                }
                sb.AppendLine("using Cinch;");
                sb.AppendLine();

                sb.AppendLine(String.Format("namespace {0}", vmToPersist.VMNamespace));
                sb.AppendLine("{");
            }
            #endregion

            //Write out data
            #region Data
            sb.AppendLine("\t/// <summary>");
            sb.AppendLine("\t///You may edit this code by hand, but there is DataWrapper code");
            sb.AppendLine("\t///and some boiler plate code provided here, to help you on your way.");
            sb.AppendLine("\t///A lot of which is actually quite useful, and a lot of thought has been");
            sb.AppendLine("\t///put into, what code to place in which file parts, and this custom part");
            sb.AppendLine("\t///does have some excellent starting code, so use it as you wish.");
            sb.AppendLine("\t///");
            sb.AppendLine("\t///But please note : One area that will need to be examined closely if you decide to introduce");
            sb.AppendLine("\t///New DataWrapper<T> properties in this part, is the IsValid override");
            sb.AppendLine("\t///Which will need to include the dataWrappers something like:");
            sb.AppendLine("\t///<pre>");
            sb.AppendLine("\t///       return base.IsValid &&");
            sb.AppendLine("\t///          DataWrapperHelper.AllValid(cachedListOfDataWrappers);");
            sb.AppendLine("\t///</pre>");
            sb.AppendLine("\t/// </summary>");


            sb.AppendLine(String.Format("\tpublic partial class {0}", vmToPersist.VMName));
            sb.AppendLine("\t{");


            //write fields
            var propsWithWrappers = vmToPersist.VMProperties.Where(x => x.UseDataWrapper == true);
            if (propsWithWrappers.Count() > 0)
            {
                sb.AppendLine("\t\t#region Data");
                sb.AppendLine("\t\tprivate IEnumerable<DataWrapperBase> cachedListOfDataWrappers;");
                sb.AppendLine("\t\tprivate ViewMode currentViewMode = ViewMode.AddMode;");
                sb.AppendLine("\t\t//Example rule declaration : YOU WILL NEED TO DO THIS BIT");
                sb.AppendLine("\t\t//private static SimpleRule quantityRule;");
                sb.AppendLine("\t\t#endregion");
            }
            sb.AppendLine();
            #endregion

            //Ctor
            #region Ctor
            sb.AppendLine("\t\t#region Ctor");
            sb.AppendLine(String.Format("\t\tpublic {0}()", vmToPersist.VMName));
            sb.AppendLine("\t\t{");


            //write out auto generated part callbacks
            sb.AppendLine();
            sb.AppendLine("\t\t\t#region Create Auto Generated Property Callbacks");
            sb.AppendLine("\t\t\t//Create callbacks for auto generated properties in auto generated partial class part");
            sb.AppendLine("\t\t\t//Which allows this part to know when a property in the generated part changes");
            foreach (var prop in vmToPersist.VMProperties)
            {
                sb.AppendLine(prop.CustomPartCtorCallBack);
            }
            sb.AppendLine("\t\t\t#endregion");



            //write out wrappers if they are needed
            if (propsWithWrappers.Count() > 0)
            {
                sb.AppendLine("\t\t\t#region Create DataWrappers");
                foreach (var propWithWrapper in propsWithWrappers)
                {
                    sb.AppendLine(propWithWrapper.ConstructorDeclaration);
                }

                sb.AppendLine("\t\t\t//fetch list of all DataWrappers, so they can be used again later without the");
                sb.AppendLine("\t\t\t//need for reflection");
                sb.AppendLine("\t\t\tcachedListOfDataWrappers =");
                sb.AppendLine(String.Format(
                                  "\t\t\t    DataWrapperHelper.GetWrapperProperties<{0}>(this);", vmToPersist.VMName));
                sb.AppendLine("\t\t\t#endregion");
            }



            //write out example validation, if this ViewModel type supports them
            if (vmToPersist.VMType != ViewModelType.Standard)
            {
                sb.AppendLine();
                sb.AppendLine("\t\t\t//    #region TODO : You WILL need to create YOUR OWN validation rules");
                sb.AppendLine("\t\t\t//    //Here is an example of how to create a validation rule");
                sb.AppendLine("\t\t\t//    //you can use this as a guide to create your own validation rules");
                sb.AppendLine("\t\t\t//    quantity.AddRule(quantityRule);");
                sb.AppendLine("\t\t\t//    #endregion");
            }

            sb.AppendLine("\t\t}");



            //write out static Constructor
            sb.AppendLine();
            sb.AppendLine(String.Format("\t\tstatic {0}()", vmToPersist.VMName));
            sb.AppendLine("\t\t{");
            sb.AppendLine("\t\t\t//quantityRule = new SimpleRule(\"DataValue\", \"Quantity can not be < 0\",");
            sb.AppendLine("\t\t\t//          (Object domainObject)=>");
            sb.AppendLine("\t\t\t//          {");
            sb.AppendLine("\t\t\t//              DataWrapper<Int32> obj = (DataWrapper<Int32>)domainObject;");
            sb.AppendLine("\t\t\t//              return obj.DataValue <= 0;");
            sb.AppendLine("\t\t\t//          });");
            sb.AppendLine("\t\t}");

            sb.AppendLine("\t\t#endregion");
            #endregion

            //Write out actual auto generated property changed callback stubs
            #region Property Changed Stubs
            sb.AppendLine();
            sb.AppendLine("\t\t#region Auto Generated Property Changed CallBacks");
            sb.AppendLine("\t\t//Callbacks which are called whenever an auto generated property in auto generated partial class part changes");
            sb.AppendLine("\t\t//Which allows this part to know when a property in the generated part changes");
            foreach (var prop in vmToPersist.VMProperties)
            {
                sb.AppendLine(prop.CustomPartActualCallBack);
            }

            sb.AppendLine("\t\t#endregion");
            #endregion

            //region ViewMode property
            #region ViewMode property (which allows all DataWrappers to be put into a specific ViewMode state)
            if (propsWithWrappers.Count() > 0)
            {
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// The current ViewMode, when changed will loop");
                sb.AppendLine("\t\t/// through all nested DataWrapper objects and change");
                sb.AppendLine("\t\t/// their state also");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tstatic PropertyChangedEventArgs currentViewModeChangeArgs =");
                sb.AppendLine(String.Format(
                                  "\t\t    ObservableHelper.CreateArgs<{0}>(x => x.CurrentViewMode);",
                                  vmToPersist.VMName));
                sb.AppendLine();
                sb.AppendLine("\t\tpublic ViewMode CurrentViewMode");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    get { return currentViewMode; }");
                sb.AppendLine("\t\t    set");
                sb.AppendLine("\t\t    {");
                sb.AppendLine("\t\t        currentViewMode = value;");
                sb.AppendLine("\t\t        //Now change all the cachedListOfDataWrappers");
                sb.AppendLine("\t\t        //Which sets all the Cinch.DataWrapper<T>s to the correct IsEditable");
                sb.AppendLine("\t\t        //state based on the new ViewMode applied to the ViewModel");
                sb.AppendLine("\t\t        //we can use the Cinch.DataWrapperHelper class for this");
                sb.AppendLine("\t\t        DataWrapperHelper.SetMode(");
                sb.AppendLine("\t\t            cachedListOfDataWrappers,");
                sb.AppendLine("\t\t            currentViewMode);");
                sb.AppendLine();
                sb.AppendLine("\t\t        NotifyPropertyChanged(currentViewModeChangeArgs);");
                sb.AppendLine("\t\t    }");
                sb.AppendLine("\t\t}");
            }
            #endregion


            //Overrides (IsValid)
            #region Overrides
            if (vmToPersist.VMType != ViewModelType.Standard)
            {
                sb.AppendLine();
                sb.AppendLine("\t\t#region Overrides");
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// Override hook which allows us to also put any child ");
                sb.AppendLine("\t\t/// EditableValidatingObject objects IsValid state into");
                sb.AppendLine("\t\t/// a combined IsValid state for the whole ViewModel,");
                sb.AppendLine("\t\t/// should you need to do so");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tpublic override bool IsValid");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    get");
                sb.AppendLine("\t\t    {");
                if (propsWithWrappers.Count() > 0)
                {
                    sb.AppendLine("\t\t       //return base.IsValid and use DataWrapperHelper, as you are");
                    sb.AppendLine("\t\t       //using DataWrappers");
                    sb.AppendLine("\t\t       return base.IsValid &&");
                    sb.AppendLine("\t\t          DataWrapperHelper.AllValid(cachedListOfDataWrappers);");
                }
                else
                {
                    sb.AppendLine("\t\t       //simply return base.IsValid as you are not");
                    sb.AppendLine("\t\t       //using DataWrappers");
                    sb.AppendLine("\t\t       return base.IsValid;");
                }
                sb.AppendLine("\t\t    }");
                sb.AppendLine("\t\t}");
                sb.AppendLine("\t\t#endregion");
            }
            #endregion

            sb.AppendLine("\t}");
            if (shouldEmit)
            {
                sb.AppendLine("}");
            }

            return(sb.ToString());
        }
Beispiel #13
0
        /// <summary>
        /// Creates and returns an auto generated part String, based on the vmToPersist
        /// parameter. The returned string will form tne auto generated part (.g.cs)
        /// </summary>
        private static String CreateAutoGeneratedPart(PesistentVM vmToPersist, Boolean shouldEmit)
        {
            StringBuilder sb = new StringBuilder(1000);

            //Write out namespaces
            #region Namespaces
            sb.AppendLine("using System;");
            sb.AppendLine("using System.Collections.Generic;");
            sb.AppendLine("using System.Linq;");
            sb.AppendLine("using System.ComponentModel;");
            sb.AppendLine("using System.Collections.ObjectModel;");
            sb.AppendLine("using System.Windows.Data;");
            sb.AppendLine("using System.Collections.Specialized;");

            //write out referenced assemblies Using statements
            List <String> refAssUsingStments =
                ReferencedAssembliesHelper.GetReferencedAssembliesUsingStatements();
            if (refAssUsingStments.Count > 0)
            {
                sb.AppendLine();
                sb.AppendLine("//Referenced assemblies");
                foreach (String usingStmnt in refAssUsingStments)
                {
                    sb.AppendLine(usingStmnt);
                }
                sb.AppendLine();
            }
            sb.AppendLine("using Cinch;");
            sb.AppendLine();
            #endregion

            #region Class code
            sb.AppendLine(String.Format("namespace {0}", vmToPersist.VMNamespace));
            sb.AppendLine("{");

            sb.AppendLine("\t/// <summary>");
            sb.AppendLine("\t///NOTE : This class was auto generated by a tool");
            sb.AppendLine("\t///Edit this code at your peril!!!!!!");
            sb.AppendLine("\t/// </summary>");

            sb.AppendLine(String.Format("\tpublic partial class {0} : Cinch.{1}",
                                        vmToPersist.VMName, vmToPersist.InheritenceVMType.ToString()));
            sb.AppendLine("\t{");

            //write Data
            #region Data
            sb.AppendLine("\t\t#region Data");
            foreach (var prop in vmToPersist.VMProperties)
            {
                sb.AppendLine(prop.FieldDeclaration);
            }
            sb.AppendLine("\t\t//callbacks to allow auto generated part to notify custom part, when property changes");
            sb.AppendLine("\t\tprivate Dictionary<String, Action> autoPartPropertyCallBacks = new Dictionary<String, Action>();");
            sb.AppendLine("\t\t#endregion");
            sb.AppendLine("\r\n");
            #endregion

            //write get/set declarations
            #region Props
            sb.AppendLine("\t\t#region Public Properties");
            foreach (var prop in vmToPersist.VMProperties)
            {
                sb.AppendLine(prop.PropGetSet);
            }
            sb.AppendLine("\t\t#endregion");
            #endregion

            #region EditableValidatingObject overrides

            var propsWithWrappers =
                vmToPersist.VMProperties.Where(x => x.UseDataWrapper == true);


            //EditableValidatingObject overrides
            if (vmToPersist.VMType == ViewModelType.ValidatingAndEditable &&
                propsWithWrappers.Count() > 0)
            {
                sb.AppendLine("\t\t#region EditableValidatingObject overrides");

                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// Override hook which allows us to also put any child");
                sb.AppendLine("\t\t/// EditableValidatingObject objects into the BeginEdit state");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tprotected override void OnBeginEdit()");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    base.OnBeginEdit();");
                sb.AppendLine("\t\t    //Now walk the list of properties in the ViewModel");
                sb.AppendLine("\t\t    //and call BeginEdit() on all Cinch.DataWrapper<T>s.");
                sb.AppendLine("\t\t    //we can use the Cinch.DataWrapperHelper class for this");
                sb.AppendLine("\t\t    DataWrapperHelper.SetBeginEdit(cachedListOfDataWrappers);");
                sb.AppendLine("\t\t}");
                sb.AppendLine();
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// Override hook which allows us to also put any child");
                sb.AppendLine("\t\t/// EditableValidatingObject objects into the EndEdit state");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tprotected override void OnEndEdit()");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    base.OnEndEdit();");
                sb.AppendLine("\t\t    //Now walk the list of properties in the ViewModel");
                sb.AppendLine("\t\t    //and call CancelEdit() on all Cinch.DataWrapper<T>s.");
                sb.AppendLine("\t\t    //we can use the Cinch.DataWrapperHelper class for this");
                sb.AppendLine("\t\t    DataWrapperHelper.SetEndEdit(cachedListOfDataWrappers);");
                sb.AppendLine("\t\t}");
                sb.AppendLine();
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// Override hook which allows us to also put any child ");
                sb.AppendLine("\t\t/// EditableValidatingObject objects into the CancelEdit state");
                sb.AppendLine("\t\t/// </summary>");
                sb.AppendLine("\t\tprotected override void OnCancelEdit()");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t    base.OnCancelEdit();");
                sb.AppendLine("\t\t    //Now walk the list of properties in the ViewModel");
                sb.AppendLine("\t\t    //and call CancelEdit() on all Cinch.DataWrapper<T>s.");
                sb.AppendLine("\t\t    //we can use the Cinch.DataWrapperHelper class for this");
                sb.AppendLine("\t\t    DataWrapperHelper.SetCancelEdit(cachedListOfDataWrappers);");
                sb.AppendLine("\t\t}");
                sb.AppendLine("\t\t#endregion");
            }
            #endregion


            #endregion

            sb.AppendLine("\t}");

            if (shouldEmit)
            {
                sb.AppendLine("}");
            }

            return(sb.ToString());
        }
Beispiel #14
0
        /// <summary>
        /// Saves the current ViewModel as an XML file or generates C# code for the
        /// current ViewModel
        /// </summary>
        /// <param name="filter">The save file filter to use</param>
        /// <param name="operation">The SaveOrGenerate operation to use</param>
        private Tuple<Boolean,String> SaveOrGenerateOperation(String filter, SaveOrGenerate operation)
        {
            if (!IsValid)
            {
                messageBoxService.ShowError("The current ViewModel is InValid\r\nPlease fix it then retry");
                return null;
            }
            else
            {
                //Ask the user where they want to save the file, and save it
                try
                {
                    saveFileService.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
                    saveFileService.FileName = String.Empty;
                    saveFileService.Filter = filter;
                    saveFileService.OverwritePrompt = true;
                    bool? result = saveFileService.ShowDialog(null);

                    if (result.HasValue && result.Value)
                    {
                        //Create a Persistence ViewModel based on the current In Memory ViewModel
                        PesistentVM pesistentVM = new PesistentVM();
                        pesistentVM.VMName = ViewModelName;
                        pesistentVM.VMType = CurrentViewModelType;
                        pesistentVM.VMNamespace = ViewModelNamespace;

                        foreach (SinglePropertyViewModel propVM in propertiesViewModel.PropertyVMs)
                        {
                            pesistentVM.VMProperties.Add(new
                                PesistentVMSingleProperty
                            {
                                PropertyType = propVM.PropertyType,
                                PropName = propVM.PropName,
                                UseDataWrapper = propVM.UseDataWrapper,
                                ParentViewModelName = ViewModelName
                            });
                        }


                        bool success = false;

                        FileInfo file = new FileInfo(saveFileService.FileName);

                        //decide what file needs saving/generating
                        switch (operation)
                        {
                            case SaveOrGenerate.Save:
                                //save to XML
                                success = ViewModelPersistence.PersistViewModel(
                                    saveFileService.FileName,pesistentVM);
                                ShowSaveOrGenMessage(success, file.Name, SaveOrGenerate.Save);
                                return TupleHelper.New(success, saveFileService.FileName);
                            case SaveOrGenerate.Generate:
                                //generate code
                                success = ViewModelPersistence.CreateViewModelCode(
                                    saveFileService.FileName, pesistentVM);
                                ShowSaveOrGenMessage(success, file.Name, SaveOrGenerate.Generate);
                                return TupleHelper.New(success, saveFileService.FileName);
                        }
                    }

                }
                catch (Exception ex)
                {
                    messageBoxService.ShowError(
                        String.Format("An error occurred trying to {0} the ViewModel\r\n{1}",
                        operation.ToString(), ex.Message));
                    return null;
                }
                return null;
            }
        }