Search Results for

    Show / Hide Table of Contents

    FlexCalc (C# / ios-unified)

    Note

    This demo is available in your FlexCel installation at <FlexCel Install Folder>\samples\csharp\VS2022\ios-unified\FlexCalc and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​NET-​demos/​tree/​master/​csharp/​VS2022/​ios-​unified/​FlexCalc

    Overview

    This example shows how to use the FlexCel calculating engine as a calculator for the device.

    Under the hood, every textbox in the app is mapped to a cell in a spreadsheet (A1, A2, A3...), and whenever a textbox changes, the sheet is recalculated and the results of the new calculations are shown at the column on the right. You can use the full range of Excel functions in this demo, and reference cells in the usual way (for example, you can write "=A2 + 1" in the textbox for A3)

    As in Excel, any text that starts with "=" will be considered a formula.

    The backing spreadsheet will be saved when you exit the app and loaded when open it, and this will allow to persist the formulas between sessions.

    Files

    AppDelegate.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Foundation;
    using UIKit;
    
    namespace FlexCalc
    {
        // The UIApplicationDelegate for the application. This class is responsible for launching the 
        // User Interface of the application, as well as listening (and optionally responding) to 
        // application events from iOS.
        [Register ("AppDelegate")]
        public partial class AppDelegate : UIApplicationDelegate
        {
            // class-level declarations
            public override UIWindow Window
            {
                get;
                set;
            }
            // This method is invoked when the application is about to move from active to inactive state.
            // OpenGL applications should use this method to pause.
            public override void OnResignActivation(UIApplication application)
            {
            }
            // This method should be used to release shared resources and it should store the application state.
            // If your application supports background exection this method is called instead of WillTerminate
            // when the user quits.
            public override void DidEnterBackground(UIApplication application)
            {
                ((FlexCalcViewController)(Window.RootViewController)).SaveConfig();
            }
    
            /// This method is called as part of the transiton from background to active state.
            public override void WillEnterForeground(UIApplication application)
            {
            }
    
            /// This method is called when the application is about to terminate. Save data, if needed. 
            public override void WillTerminate(UIApplication application)
            {
                ((FlexCalcViewController)(Window.RootViewController)).SaveConfig();
            }
    
            public override void FinishedLaunching(UIApplication application)
            {
            }
    
    
        }
    }
    

    CalcCell.cs

    // This file has been autogenerated from a class added in the UI designer.
    
    using System;
    
    using Foundation;
    using UIKit;
    using CoreGraphics;
    using System.Drawing;
    
    namespace FlexCalc
    {
        public partial class CalcCell : UICollectionViewCell
        {
            private UILabel CellHeading;
            private UITextView CellContent;
            private UILabel CellResult;
            public int XlsRow{ get; set; }
            public Action<CalcCell> ActiveCell{ get; set; }
    
            [Export ("initWithFrame:")]
            public CalcCell (System.Drawing.RectangleF frame) : base (frame)
            {  
                CellHeading = new UILabel(new RectangleF(5, 5, 35, 40));
                CellHeading.TextColor = UIColor.DarkTextColor;
                ContentView.AddSubview(CellHeading);
    
    
                CellContent = new UITextView(new RectangleF(45, 5, 135, 40));
    
                CellContent.ReturnKeyType = UIReturnKeyType.Done;
                CellContent.Delegate = new CalcTextViewDelegate(x => ActiveCell( x == null? null: this), ()=> OnRefresh(this));
                CellContent.KeyboardType = UIKeyboardType.NumbersAndPunctuation;
    
                ContentView.AddSubview(CellContent);
    
                CellResult = new UILabel(new RectangleF(180, 5, frame.Width - 180 - 10, 40));
                CellResult.TextColor = UIColor.DarkTextColor;
                CellResult.TextAlignment = UITextAlignment.Right;
                ContentView.AddSubview(CellResult);
            }
    
            public Action<CalcCell> OnRefresh { get; set; }
    
            public string Heading{ set { CellHeading.Text = value; } }
            public string Content{ get { return CellContent.Text; } set { CellContent.Text = value; } }
            public string Result { set { CellResult.Text = value; } }
    
        }
    
        class CalcTextViewDelegate: UITextViewDelegate
        {
            Action<UITextView> SetActive;
            Action OnRefresh;
    
            public CalcTextViewDelegate(Action<UITextView> setActive, Action onRefresh)
            {
                SetActive = setActive;
                OnRefresh = onRefresh;
            }
    
            public override bool ShouldChangeText(UITextView textView, NSRange range, string text)
            {
                if (text == "\n")
                {
                    textView.ResignFirstResponder();
                    return false;
                }
                return true;
            }
    
            public override void Changed(UITextView textView)
            {
                OnRefresh();
            }
    
            public override void EditingStarted(UITextView textView)
            {
                SetActive(textView);
            }
    
            public override void EditingEnded(UITextView textView)
            {
                SetActive(null);
            }
    
        }
    }
    

    CalcCell.designer.cs

    // WARNING
    //
    // This file has been generated automatically by Xamarin Studio from the outlets and
    // actions declared in your storyboard file.
    // Manual changes to this file will not be maintained.
    //
    using Foundation;
    using System;
    using System.CodeDom.Compiler;
    using UIKit;
    
    namespace FlexCalc
    {
       [Register ("CalcCell")]
        partial class CalcCell
        {
            void ReleaseDesignerOutlets ()
            {
            }
        }
    }
    

    FlexCalcViewController.cs

    using System;
    using System.Drawing;
    using Foundation;
    using UIKit;
    using FlexCel.Core;
    using FlexCel.XlsAdapter;
    using System.IO;
    using ObjCRuntime;
    
    namespace FlexCalc
    {
        public partial class FlexCalcViewController : UICollectionViewController
        {
            static NSString CalcCellId = new NSString ("CalcCell");
            string FileName
            {
                get { return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "FlexCalc.xls"); }
            }
    
            ExcelFile xls;
            CalcCell ActiveEdit;
            RectangleF keybRect;
    
            static bool UserInterfaceIdiomIsPhone
            {
                get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; }
            }
    
            public FlexCalcViewController(IntPtr handle) : base (handle)
            {
            }
    
            public override void DidReceiveMemoryWarning()
            {
                // Releases the view if it doesn't have a superview.
                base.DidReceiveMemoryWarning();
    
                // Release any cached data, images, etc that aren't in use.
            }
    
    
            #region View lifecycle
    
    
            public override void ViewWillAppear(bool animated)
            {
                base.ViewWillAppear(animated);
            }
    
            public override void ViewDidAppear(bool animated)
            {
                base.ViewDidAppear(animated);
            }
    
            public override void ViewWillDisappear(bool animated)
            {
                base.ViewWillDisappear(animated);
            }
    
            public override void ViewDidDisappear(bool animated)
            {
                base.ViewDidDisappear(animated);
            }
    
            #endregion
    
            public override void ViewDidLoad ()
            {
                base.ViewDidLoad ();
    
                xls = new XlsFile(true);
                if (File.Exists(FileName))
                    xls.Open(FileName);
                else
                    CreateInitialFile(xls);
    
                CollectionView.RegisterClassForCell (typeof(CalcCell), CalcCellId);
                FixKeyboard();
    
                var Layout = new UICollectionViewFlowLayout();
                var w = CalcCellWidth(CollectionView.Bounds.Width);
                Layout.ItemSize = new SizeF(w, 50);
                CollectionView.SetCollectionViewLayout(Layout, false);
    
                //register the keyboard so we make the text fields visible
                NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.DidShowNotification,  (x) =>
                {
                    if (ActiveEdit == null) return;
                    var keybRectObj = x.UserInfo.ObjectForKey(UIKeyboard.FrameBeginUserInfoKey);
                    keybRect = ((NSValue)keybRectObj).RectangleFValue;
                    FixKeyboard();
    
    
                    var FrameRec = View.Frame;
                    FrameRec.Height -=  keybRect.Height;
                    if (!FrameRec.Contains(ActiveEdit.Frame.Location))
                    {
                        this.CollectionView.ScrollRectToVisible(ActiveEdit.Frame, true);
                    }
                });
    
                NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.DidHideNotification, (x) =>
                {
                    keybRect = new RectangleF(0, 0, 0, 0);
                    FixKeyboard();
    
                });
    
            }
    
            void CreateInitialFile(ExcelFile xls)
            {
                xls.NewFile(1, TExcelFileFormat.v2019);
                xls.SetCellValue(1, 1, 7);
                xls.SetCellValue(2, 1, 5);
                xls.SetCellValue(3,1, new TFormula("=sum(a1:a2)^2"));
                xls.Recalc();
            }
    
            public void SaveConfig()
            {
                if (xls != null) xls.Save(FileName);
            }
    
            public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
            {
                FixKeyboard();
                var Layout = new UICollectionViewFlowLayout();
                var w = CalcCellWidth(CollectionView.Bounds.Width);
                Layout.ItemSize = new SizeF(w, 50);
                CollectionView.SetCollectionViewLayout(Layout, true);
    
            }
    
            void FixKeyboard()
            {
                if (InterfaceOrientation == UIInterfaceOrientation.Portrait || InterfaceOrientation == UIInterfaceOrientation.PortraitUpsideDown)
                {
                    CollectionView.ContentInset = new UIEdgeInsets(20, 0, keybRect.Height + 40, 0);
                }
                else
                {
                    CollectionView.ContentInset = new UIEdgeInsets(20, 0, keybRect.Width + 40, 0);
                }
            }
    
            public float CalcCellWidth(nfloat wd)
            {
                return 320;
            }
    
            public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
            {
                var cell = (CalcCell)collectionView.DequeueReusableCell (CalcCellId, indexPath);
                cell.XlsRow = indexPath.Row + 1;
                cell.Heading = new TCellAddress(indexPath.Row + 1, 1).CellRef;
                cell.Content = GetCellOrFormula(indexPath.Row + 1);
                cell.ActiveCell = x => ActiveEdit = x;
                cell.Result = xls.GetStringFromCell(indexPath.Row + 1, 1);
                cell.OnRefresh = RefreshData;
                return cell;
            }
    
            string GetCellOrFormula(int row)
            {
                object cell = xls.GetCellValue(row, 1);
                if (cell == null)
                    return "";
                TFormula fmla = (cell as TFormula);
                if (fmla != null)
                    return fmla.Text;
    
                return Convert.ToString(cell);
            }  
    
            private void RefreshData(CalcCell changedCell)
            {
                xls.SetCellFromString(changedCell.XlsRow, 1, changedCell.Content);
                xls.Recalc();
    
                foreach (CalcCell cell in CollectionView.VisibleCells)
                {
                    cell.Result = xls.GetStringFromCell(cell.XlsRow, 1);
                }
    
            }
    
            public override nint NumberOfSections (UICollectionView collectionView)
            {
                return 1;
            }
    
            public override nint GetItemsCount (UICollectionView collectionView, nint section)
            {
                return 20;
            }
    
            public override void ItemHighlighted(UICollectionView collectionView, NSIndexPath indexPath)
            {
                collectionView.EndEditing(false);
            }
    
    
        }
    }
    

    FlexCalcViewController.designer.cs

    // WARNING
    //
    // This file has been generated automatically by Xamarin Studio from the outlets and
    // actions declared in your storyboard file.
    // Manual changes to this file will not be maintained.
    //
    using Foundation;
    using System;
    using System.CodeDom.Compiler;
    using UIKit;
    
    namespace FlexCalc
    {
       [Register ("FlexCalcViewController")]
        partial class FlexCalcViewController
        {
            void ReleaseDesignerOutlets ()
            {
            }
        }
    }
    

    Main.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Foundation;
    using UIKit;
    
    namespace FlexCalc
    {
        public class Application
        {
            // This is the main entry point of the application.
            static void Main(string[] args)
            {
                // if you want to use a different Application Delegate class from "AppDelegate"
                // you can specify it here.
                UIApplication.Main(args, null, "AppDelegate");
            }
    
        }
    }
    
    In This Article
    Back to top FlexCel Studio for the .NET Framework v7.24.0.0
    © 2002 - 2025 tmssoftware.com