Blog Archive

Sunday, September 9, 2012

Hit Test Toolbar to find button


Toolbar is an ItemsControl and does not have click event handler to indicate which button is clicked. Here Hit Testing is used to figure that out:

Note that we need to use Preview to Tunneling Event Handler

       void tbr_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            ToolBar tbr = sender as ToolBar;
           
            Point pt=e.GetPosition(tbr);
            object btnClicked=null;
            UIElement element = tbr.InputHitTest(pt) as UIElement;
            while (element != null)
            {
                if (element == tbr) return;
                 btnClicked = tbr.ItemContainerGenerator.ItemFromContainer(element);
                 if (!btnClicked.Equals(DependencyProperty.UnsetValue)) break;
                element = (UIElement)VisualTreeHelper.GetParent(element);
            }
           
            if (btnClicked != null)
                Console.WriteLine((btnClicked as Button).Content);
            else
                Console.WriteLine("no item found");
        }


Saturday, August 25, 2012

WCF Duplex Client as Observer

Setup Rx observer over the wire requires WCF Duplex callback:
(1) ServiceContract need to define IObserverCallback, instead of subscrbe method lamda.
(2) Subscribe and unsubscrib() should be one-way to avoid potential blocking
(3) If Session is required then Subscribe/Unsubscrib need to be initiating/terminating
(4) Note that IO.Subcribe is non-blocking (v.s. deprecated ForEach) and its only purpose is to set up OnNext on Service side which call Client Side OnNext.
(5) Service Instancing Context must be PerSession or Single. PerCall cannot do Unsubscribe since state variable bool stopIO is not maintained. 
On the other hand, Single => Unsubscribe will stop all Sessions.
(6) Threading Issues:  WCF service as Single-Thread by default,So reentry will cause deadlock and therefore disallowed ( e.g calling Callback during Service Operation).
 So mark Service Behavior ConcurrencyMode Reentrant/Mutiple
(7) netTcp Binding is Duplex (its name did not say Dual)
(8) Update Svc Reference on Client will trigger WCF host for WCF Lib project to run for debugging/testing.
(9) Client side Auto Gen Service Reference will force Service Constructor taking in InstanceContext, which in term require Callback contract implemntation.
Service Side uses OperationContext.Current.GetCallbackChannel<IObservserCallback>();
(10) Note that Callback contract name on client is IService1Callback <> IObservserCallback service side Callback Contract Name.
(11) CPU <10% when run test with 1ms data push, no network travel.
(12) To signal Complete on an IO, use TakeWhile and check a non-blocking State Variable like stopIO=true.

Contract and Service Definition

    [ServiceContract(CallbackContract = typeof(IObservserCallback),SessionMode= SessionMode.Required)]
    public interface IService1
    {
        [OperationContract(IsOneWay=true, IsInitiating=true)]
        void Subscribe();
        [OperationContract(IsOneWay = true,IsTerminating=true)]
        void Unsubscribe();
    }

    public interface IObservserCallback
    {
        [OperationContract]
        void OnNext(CompositeType data);
    }

    [DataContract]
    public class CompositeType
    {
        double _value = 30.45;
        string _Name = "Name1";

        [DataMember]
        public double Value
        {
            get { return _value; }
            set { _value = value; }
        }

        [DataMember]
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
    }


Service

   // [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode=ConcurrencyMode.Reentrant)]
    public class Service1 : IService1
    {
        bool stopIO;  //Session State
        public void Subscribe()
        {
            stopIO = false;
            IObservserCallback client = OperationContext.Current.GetCallbackChannel<IObservserCallback>();
            var IO = Observable.Interval(TimeSpan.FromMilliseconds(1)).TakeWhile(x => { return !stopIO; });
            IO.Subscribe(x =>   // This is non-blocking
            {
              if(client!=null)
                  client.OnNext(new CompositeType() { Name ="Name"+ x.ToString(), Value=(new Random()).NextDouble()*30 });
            });
        }

        public void Unsubscribe()
        {
            stopIO = true;
        }   
    }

Client side Subscription and Observer

    class Program
    {
        static void Main(string[] args)
        {
            ServiceReference1.Service1Client c = new ServiceReference1.Service1Client(new InstanceContext(new callbackObserver()));
            c.Subscribe();
            Console.WriteLine("Wait for Data. To stop IO, hit return");
            Console.ReadLine();
            c.Unsubscribe();
            Console.ReadLine();
        }
    }

    class callbackObserver : ConsoleApplication1.ServiceReference1.IService1Callback
    {
        public void OnNext(CompositeType data)
        {
            Console.WriteLine("Data: " + data.Name +" "+data.Value.ToString());
        }
    }

Friday, August 17, 2012

Drag Canvas around using Rx

WPF UI can be Drag around using mouseMove stream Buffer of two element calculation of Delta:
(1) Observe 3 streams: mouseDown, mouseUp, mouseMove. The first two are point event and need duration to join to mouseMove.
(2) The duration is skip until mouseDown take until mouseUp
(3) Delta is the difference between two mouseMove sampling inside Buffer(2,2). Note that Buffer(count, skip) skip=count is standard, skip>count skip and skip<count is overlapping. Buffer means pile up multiple point into one tally





        public MainWindow()
        {
            InitializeComponent();

            var mouseDown = from evt in Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => cv.MouseDown += h, h => cv.MouseDown -= h)
                            select evt.EventArgs.GetPosition(this);
            var mouseUp = from evt in Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => MouseUp += h, h => MouseUp -= h)
                          select evt.EventArgs.GetPosition(this);
            var mouseMove = from evt in Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => MouseMove += h, h => MouseMove -= h)
                            select evt.EventArgs.GetPosition(this);

            var q = Observable.Join(
                mouseDown,
                mouseMove.Buffer(2, 2),
                 _ => mouseMove.SkipUntil(mouseDown).TakeUntil(mouseUp),
                _ => Observable.Empty<Unit>(),
                (d, consecPts) =>new Point(consecPts[1].X - consecPts[0].X, consecPts[1].Y - consecPts[0].Y));

            q.Subscribe(delta =>
            {
                Canvas.SetLeft(cv, Canvas.GetLeft(cv) + delta.X);
                Canvas.SetTop(cv, Canvas.GetTop(cv) + delta.Y);
            });

// Side Note: To allow resizing do the following and using Microsoft sample Resizing Adorner:
           // a = AdornerLayer.GetAdornerLayer(g); //g=Canvas for layout
           // a.Add(new ResizingAdorner(cv));  // cv= any UIElement inside g
        }
         // AdornerLayer adornerLayer;
    }


 public class ResizingAdorner : Adorner
  {
    Thumb topLeft, topRight, bottomLeft, bottomRight;

    VisualCollection visualChildren;

    public ResizingAdorner(UIElement adornedElement)
      : base(adornedElement)
    {
      visualChildren = new VisualCollection(this);
        
      BuildAdornerCorner(ref topLeft, Cursors.SizeNWSE);
      BuildAdornerCorner(ref topRight, Cursors.SizeNESW);
      BuildAdornerCorner(ref bottomLeft, Cursors.SizeNESW);
      BuildAdornerCorner(ref bottomRight, Cursors.SizeNWSE);

      bottomLeft.DragDelta  += new DragDeltaEventHandler(HandleBottomLeft);
      bottomRight.DragDelta += new DragDeltaEventHandler(HandleBottomRight);
      topLeft.DragDelta     += new DragDeltaEventHandler(HandleTopLeft);
      topRight.DragDelta    += new DragDeltaEventHandler(HandleTopRight);
    }

    #region Handle Resizing from Thumb

    void HandleBottomRight(object sender, DragDeltaEventArgs args)
    {
      FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
      Thumb hitThumb = sender as Thumb;

      if (adornedElement == null || hitThumb == null) return;
      FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;
      EnforceSize(adornedElement);

      adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
      adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);
    }

    void HandleBottomLeft(object sender, DragDeltaEventArgs args)
    {
      FrameworkElement adornedElement = AdornedElement as FrameworkElement;
      Thumb hitThumb = sender as Thumb;

      if (adornedElement == null || hitThumb == null) return;

      // Ensure that the Width and Height are properly initialized after the resize.
      EnforceSize(adornedElement);

      adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
      adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);
    }

    void HandleTopRight(object sender, DragDeltaEventArgs args)
    {
      FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
      Thumb hitThumb = sender as Thumb;

      if (adornedElement == null || hitThumb == null) return;
      FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;

      EnforceSize(adornedElement);

      adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
      adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
    }

    void HandleTopLeft(object sender, DragDeltaEventArgs args)
    {
      FrameworkElement adornedElement = AdornedElement as FrameworkElement;
      Thumb hitThumb = sender as Thumb;

      if (adornedElement == null || hitThumb == null) return;
      EnforceSize(adornedElement);
      adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
      adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
    }

    #endregion

    // Arrange thumbs relative to Adorner Center
    protected override Size ArrangeOverride(Size finalSize)
    {
      double desiredWidth  = AdornedElement.DesiredSize.Width;
      double desiredHeight = AdornedElement.DesiredSize.Height;
    
      double adornerWidth = this.DesiredSize.Width;
      double adornerHeight = this.DesiredSize.Height;

      topLeft.Arrange(new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
      topRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
      bottomLeft.Arrange(new Rect(-adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));
      bottomRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));

      return finalSize;
    }

 
    void BuildAdornerCorner(ref Thumb cornerThumb, Cursor customizedCursor)
    {
      if (cornerThumb != null) return;

      cornerThumb = new Thumb();

      // Set some arbitrary visual characteristics.
      cornerThumb.Cursor = customizedCursor;
      cornerThumb.Height = cornerThumb.Width = 10;
      cornerThumb.Opacity = 0.40;
      cornerThumb.Background = new SolidColorBrush(Colors.MediumBlue);

      visualChildren.Add(cornerThumb); // Must add to the tree to arrange
    }


    void EnforceSize(FrameworkElement adornedElement)
    {
      if (adornedElement.Width.Equals(Double.NaN)) 
        adornedElement.Width = adornedElement.DesiredSize.Width;
      if (adornedElement.Height.Equals(Double.NaN))
        adornedElement.Height = adornedElement.DesiredSize.Height;

      FrameworkElement parent = adornedElement.Parent as FrameworkElement;
      if (parent != null)
      {
        adornedElement.MaxHeight = parent.ActualHeight;
        adornedElement.MaxWidth = parent.ActualWidth;
      }
    }

    protected override int VisualChildrenCount { get { return visualChildren.Count; } }
    protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
  }

Saturday, August 11, 2012

Dualization

(1) Algebra notation indicates IO  is dual of any subject =>func pattern, especially IEnumerable<T>
(2) Monad has M, bind, return and in Continuation Monad
     CM<T> = (T ->() ) -> ()
     return :: T -> CM<T>
     bind ::  CM<T> -> (T -> CM<S>) -> CM<S>




Daulality Code

interface IEnumerable<out T> {
      IEnumerator<T> GetEnumerator(); }

interface IEnumerator<out T>: IDisposable {
       bool MoveNext();
       T Current { get; } }

interface IObservable<out T> {
   IDisposable Subscribe(IObserver<T> observer);  }

interface IObserver<in T>  {
   void OnCompleted(bool done);
   void OnError(Exception exception);
   T OnNext { set; }  }



Covariant vs. Contravariant
  A <: B     A is subtype of B,for TypeContructor C
  C<A> <: C<B>   (Covariant)
  C<B> <: C<A>   (Contravariant)
   
Reading = Covar = <out T>
Writing = Contra = <in T> =pass args into array.

    interface IRequireContravariant<in T> { int Write(T t); }

    interface IRequireCovariant<out T>{ T Read(int t);  }    


IE vs. IO
(1) Concurrency: IE need to remove Concurrency and block MoveNext until Source
ready for Next Value; IO need to add Concurrency to not block source push to target
(2) Async Computation Model
         void Fib( int n, ACtion CB, Action Err, Action Cncl)
         IObserver Fib(int n);
(3) IE can sample source interactively while IO cannot push back high speed source. So IScheduler is define to have time specified:
          IScheduler {
              DateTimeOffset Now
              IDisposable Schedule(state, DateTimeOffset dueTime, Func action)
              IDisposable Schedule(..TimeSpan dueTime,..);
              IDisposable Schedule(TState state, Func action)  // constant push
}

Sunday, August 5, 2012

Prism Region Manager, Sevice Locator and Module


Some code to demo additional features of Prism
(1) ServiceLocator.GetInstance = Container.Resolve and inject
(2) Region Manager can define region for injecting UserControl (view)
(3) Module execute injection of view
(4) Adding Module to ModuleCatalog does injection of Region Manager

App run bootstrapper

   public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            OtherBootstrapper b = new OtherBootstrapper();
            b.Run(); 
        }
    }
Bootstrapper: Service Locator, ModuleCatalog

   public class OtherBootstrapper :  UnityBootstrapper
    {
        protected override void InitializeShell()
        {
            (Application.Current.MainWindow = (Window)Shell).Show();
        }

        protected override DependencyObject CreateShell()
        {
            //ServiceLocator replaced Container.Resolve
           return ServiceLocator.Current.GetInstance<ShellWin>();
          //  return Container.TryResolve<ShellWin>();         }

        protected override void ConfigureContainer()
        {
           // this will run default config such as EventAggregator, ServiceLocator and region manager
            base.ConfigureContainer();          
        }

        protected override void ConfigureModuleCatalog()
        {
            // amazingly, add ModuelInfo will do DI just like container.Resolve
            ModuleCatalog.AddModule(new ModuleInfo()
            {
                ModuleName = typeof(OtherFeatureModule).Name,
                ModuleType = typeof(OtherFeatureModule).AssemblyQualifiedName
            });
            base.ConfigureModuleCatalog();
        }
    }

   public class OtherFeatureModule : IModule
    {
        IRegionManager _mgr;
        // DI does happend when ModuleInfor Added to Catalog
        public OtherFeatureModule(IRegionManager mgr)
        {
            _mgr = mgr;
        }
        public void Initialize()
        {
            _mgr.Regions["mainReg"].Add(new uc1 ());
        }
    }

ShellWin.xaml  --- Region added to RegionManager.Region Collection
    xmlns:ps="http://www.codeplex.com/CompositeWPF"
    <Grid>
        <ContentControl ps:RegionManager.RegionName="mainReg" />
    </Grid>

Tuesday, July 31, 2012

Parallel.For vs. Synchronization using ManualResetEvent

For 100 threads Synchronization using primitives seems a bit fater, 14s vs. 17s
(but for some reason WCF does not go parallel even after adjusted throtlelling=100
machine.config processModel min/max work/Id thread =100/200)
    class Program
    {
        private const int NUM = 100;
        static CountdownEvent cde = new CountdownEvent(NUM);
        static ManualResetEvent mre = new ManualResetEvent(false);
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            PFor();
          //  SyncWithPrimitives();
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadKey();
        }

        private static void PFor()
        {
            c.Open();
            Parallel.For(0, NUM, new ParallelOptions() {MaxDegreeOfParallelism=NUM}, (i) =>
            {
                c.GetData(1111);
              //  Console.WriteLine(c.GetData(1111));
            });
            c.Close();
        }

        #region Using Threading Primitives

        private static void SyncWithPrimitives()
        {
            Thread[] threads = new Thread[NUM];
            for (int i = 0; i < NUM; i++)
            {
                threads[i] = new Thread(SetThread);
                threads[i].Start();
            }
            cde.Wait();
            c.Open();
            mre.Set();  // all threads burst into calling WCF

            cde = new CountdownEvent(NUM);  // count down to all finish calls to WCF
            cde.Wait();
            c.Close();
        }

        static ServiceReference1.Service1Client c = new ServiceReference1.Service1Client();
        static void SetThread()
        {
            cde.Signal();
            mre.WaitOne();
            c.GetData(1111);
          // Console.WriteLine( c.GetData(1111));
            cde.Signal();  // call finished
        }

        #endregion

    }

WCF:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            Random r = new Random();
            Thread.Sleep(TimeSpan.FromSeconds(1));
            return r.NextDouble().ToString();
        }

Monday, July 30, 2012

Implement Asyn WCF using Task in .Net 4.0

In Fx 4.5 Task can be returned but in Fx 4.0, task can only be on Server:

    public interface IService1
    {
        [OperationContract(AsyncPattern=true)]
        IAsyncResult BeginGetDataAsync(int value, AsyncCallback cb, object state);

         string EndGetDataAsync(IAsyncResult ar);
    }

         string GetData(int value)
        {
            Random r = new Random();
            Thread.Sleep(TimeSpan.FromSeconds(3));
            return r.NextDouble().ToString();
        }

        public IAsyncResult BeginGetDataAsync(int value, AsyncCallback cb, object state)
        {
            var t = Task<string>.Factory.StartNew((s) => { return GetData(value); },state);  // must pass state into Lambda
            return t.ContinueWith(res => cb(t));

        }

        public string EndGetDataAsync(IAsyncResult ar)
        {
            return ((Task<string>)ar).Result;
        }


Client --- need to add Servicew Ref with support of async WCF checked

            object state = "";
            ServiceReference1.Service1Client c = new ServiceReference1.Service1Client();
           

            int NUM = 10;

            Stopwatch sw= new Stopwatch();
            sw.Start();

            Parallel.For(0, NUM, (ls) =>
                {
                    //for (int i = 0; i < NUM; i++)
                    //{
                    var t = Task<string>.Factory.FromAsync(c.BeginGetDataAsync, c.EndGetDataAsync, 10, state);
                    string s = t.Result;
                    Console.WriteLine(s);
                    //}
                });

     
            c.Close();
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();

Wednesday, July 25, 2012

High Performance WPF/WCF


Serveral Keys for High Performance:
(1) WPF need to use ThreadPool (Task/ParallelFor) to call WCP in the backgroud
(2) Return data should be on Queues for Dispatcher Timer to pick up and update UI
(3) WCF Instancing.Single and Concurrency.Multiple seems to have better network 
through-put than Single/Single 
( Total B/Sec in Win8 Resource Monitor 220 vs 280, 20%+). But this not a serious performance Testing)
(4) one thing for sure: when Task is removed, UI will be slugish.





   public delegate void OnHeartbeat();
  
    public partial class MainWindow : Window
    {
        const int NUM = 5000;
        public event OnHeartbeat Heartbeat;
        DispatcherTimer t;
        DispatcherTimer t2;
        List<RealtimeData> dataList = new List<RealtimeData>();
        Dictionary<int, Queue> qList = new Dictionary<int, Queue<string>>();

        public MainWindow()
        {
            InitializeComponent();
            t = new DispatcherTimer() { Interval = new TimeSpan(0, 0, 0, 0, 1) };
            t.Tick += new EventHandler(t_Tick);
            t2 = new DispatcherTimer() { Interval = new TimeSpan(0, 0, 0, 0, 1) };
            t2.Tick += new EventHandler(t_Tick2);
            AddGridCell();
            t.Start();
            t2.Start();
        }

        void t_Tick(object sender, EventArgs e)
        {
            if (Heartbeat != null) Heartbeat();
        }

        void t_Tick2(object sender, EventArgs e)
        {
   
            Task.Factory.StartNew(() =>
            {
                Parallel.For(0, NUM, (ii) =>
               // for (int ii = 0; ii < NUM; ii++)
                {
                    try
                    {
                        ServiceReference1.Service1Client c = new ServiceReference1.Service1Client();
                        qList[ii].Enqueue(c.GetData(ii));
                        c.Close();
                    }
                    catch (Exception ex)
                    {
                        EventLog.WriteEntry("Application", ex.Message + " " + ex.StackTrace);
                    }
                });
               // }
            });
        }

        void AddGridCell()
        {

            for (int i = 0; i < NUM; i++)
            {
                qList.Add(i, new Queue());
                RealtimeData rtD = MakeDataItem(i);
                this.Heartbeat += rtD.UpdateData;
                dataList.Add(rtD);
                wrapPanel1.Children.Add(rtD);
            }
        }

  
        RealtimeData MakeDataItem(int i)
        {
            return new RealtimeData(qList[i]) { Width = 50, Height = 50, BorderBrush = new SolidColorBrush(Colors.Black), BorderThickness = new Thickness(2) };
        }

      
    
    }

    public class RealtimeData : UserControl
    {
        Label lb = new Label();
        Queue<string> _q; 
        public RealtimeData(Queue<string> q)
        {
            _q = q;
            this.AddChild(lb);
        }

        public void UpdateData()
        {
            int i = _q.Count;
            if (_q.Count > 0) lb.Content =i.ToString()+" "+ _q.Dequeue();
        }
 
    }




  // [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
    public class Service1 : IService1
    {
      
        public string GetData(int value)
        {
          //  Thread.SpinWait(300000);
            Random r = new Random();
            return string.Format(r.NextDouble().ToString());
        }

    }

Tuesday, July 17, 2012

WPF Prism MVVM using Unity and Mef

Summary: We need to Unity/Mef Bootstrap into Shell as Top Window, where two things
happen: the normal WPF Window.Show() and enable Dependency Injection (DI) as early
 as possible using UnityContainer.Resolve<Shell> or 
CompositeContainer.GetExportTypes<>. Note that basic services like
 EventAggregator are constructed by Unity/Mef and will be passed along through 
Container/Aggregate Catalog.
Note that WPF DataContext is set in ShellWindos Constructor for Unity and DInjected
 for Mef through [Import].


bootstrapper.cs

    #region Unity Bootstrapper

    class DemoUnityBootstrapper : UnityBootstrapper
    {

        protected override System.Windows.DependencyObject CreateShell()
        {
            return  Container.Resolve<ShellWindow>();  // must be resolved by Container to do DI
        }
        protected override void InitializeShell()
        {
            (Application.Current.MainWindow =(Window) Shell).Show();
        }

    }

    #endregion

    #region Mef Bootstrapping

    class DemoMefBootstrapper : MefBootstrapper
    {

        protected override System.Windows.DependencyObject CreateShell()
        {
            return new ShellWindow2(Container,AggregateCatalog);  //avoid DI [Export] on ShellWindow2
        }

        protected override void InitializeShell()
        {
            (Application.Current.MainWindow = (Window)Shell).Show();
        }

    }

    #endregion

App Startup

        protected override void OnStartup(StartupEventArgs e)
        {
                DemoUnityBootstrapper dub = new DemoUnityBootstrapper();
                dub.Run(true);

                DemoMefBootstrapper dmb = new DemoMefBootstrapper();
                dmb.Run(true);           
        }


Shell as Window

        public ShellWindow(IUnityContainer container)  //DI
        {
            InitializeComponent();
            // again, DI require Container.Resolve.
            var vm = container.Resolve<PrismDemo.MVVM.ViewModel>();
            var view = container.Resolve<PrismDemo.MVVM.View>();

            view.DataContext = vm;
            cc.Content = view;
        }

        public ShellWindow2(CompositionContainer c, AggregateCatalog a) //not DI
        {
            InitializeComponent();
           
            a.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
            IView v2 = c.GetExportedValue<IView>();  // invoke  Import-Export matching on V
            cc.Content = v2;
        }

View for Mef only, Unity has no code

    [Export(typeof(IView))]  // for Container.GetExport
    public partial class View2 : UserControl , IView
    {
        public View2()
        {
            InitializeComponent();
        }

        [Import]  // Import will Match Export of VM2
        public ViewModel2 ViewModel
        {
            set { this.DataContext = value; }
        }

        // declare which view is it for Modularity
        public string ViewName
        {
            get
            {
                return "View2";
            }
            set
            {
                throw new NotImplementedException();
            }
        }
    }

Xaml
    <Grid>
       <StackPanel>
        <TextBlock Background="#FF15ABB7">MVVM View, Data binding</TextBlock> 
        <TextBox Text="{Binding Path=SingleValue, Mode=TwoWay}" />
        </StackPanel>
    </Grid>


ViewMode

    public class ViewModel : INotifyPropertyChanged
    {
        IEventAggregator _eventAggregator;
        public ViewModel(IEventAggregator ea)  //Unity Ctor DI
        {
            _eventAggregator = ea;
        }

        string _SingleValue="test";
        public string SingleValue
        {
            get { return _SingleValue;}
            set 
            {
                _SingleValue=value;
                PropertyChanged(this, new PropertyChangedEventArgs("SingleValue"));
                Debug.Assert(_eventAggregator != null);  // test Event Aggregator get DInjected
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    [Export(typeof(ViewModel2))]
    public class ViewModel2 : NotificationObject 
    {
        [Import]  // Exported by Mef base Aggregate Catalog
        public IEventAggregator ea { get; set; }

        IEventAggregator propEa;
        [ImportingConstructor]
        public ViewModel2(IEventAggregator ea2)
        {
            propEa = ea2;
        }


        string _SingleValue = "test";
        public string SingleValue
        {
            get { return _SingleValue; }
            set
            {
                _SingleValue = value;
                RaisePropertyChanged("SingleValue");
                Debug.Assert(ea != null & propEa != null); // test Event Aggregator get DInjected as Ctor and Prop
            }
        }
    }




Saturday, July 14, 2012

Trading Signals from EMA and RSI

[hist_date, hist_high, hist_low, hist_open, hist_close, hist_vol] =get_hist_stock_data('AAPL','2012');
data=hist_close;
[lead,lag]=movavg(data,5,20,'e');
s=zeros(size(data));
s(lead<=lag)=-1;
s(lead>lag)=1;
r=[0;s(1:end-1).*diff(data)];
R=cumsum(r);

% ax(1) = subplot(2,1,1);
% plot([data,lead,lag]); grid on
% legend('Close','Lead','Lag','Location','Best')
% title(['Data, Lead and Lag MA'])
% ax(2) = subplot(2,1,2);
% plot([s*50,cumsum(r)]); grid on
% legend('signal long and short','Cumulative Return','Location','Best')
% linkaxes(ax,'x')

rsi=rsindex(data,14)
s1=zeros(size(data));
s1(rsi>75)=-1;
s1(rsi<25)=1;
r1=[0;s1(1:end-1).*diff(data)];
R1=cumsum(r);

ax(1) = subplot(2,1,1);
plot([data]); grid on
legend('Close','Location','Best')
title(['Close'])
ax(2) = subplot(2,1,2);
plot([s1*25,R1]); grid on
legend('RSI Signal long short,no action','Cumulative Return','Location','Best')
linkaxes(ax,'x')

Interesting javascript code


Get Radio button value and update Telerik Paging for refresh presevation
   // F12 and debugger showed the structure
    $(document).ready(function() {
        var rb = $("input[id='rbfilterType']:radio:checked").attr('value');
        $("a[href*='TheGrid-page']").each(function(i) {
            var h = this.href;
            this.href =replaceQueryString(this.href, "filterType",rb);
        }
       );
    }
    )
    function replaceQueryString(url, param, value) {
        var re = new RegExp("([?|&])" + param + "=.*?(&|$)", "i");
        if (url.match(re))
            return url.replace(re, '$1' + param + "=" + value + '$2');
        else
            return url + '&' + param + "=" + value;
    } 

Using CSS Scrollbar to replace malfunction Teleric Scrollbar
 // find the inner table and add scrollbar heigth to hide v-bar
    $(document).ready(function() {
        var h = $("#grdTestList table").height();
        var h1 = h + 45;
        $("#grdTestList").attr("style", "overflow:auto;height:"+h1+"px");

    }
    )

Refreshing

<input type="button" value="Close and Refresh" onclick="javascript:document.location.reload();" />

            <input type="button" value="Close and Refresh" onclick="javascript:Window_onClose();" />
    
    
    <script type="text/javascript">
        function Window_onClose() {
            var window = $('#editDialog').data('tWindow');
            window.close();
            document.getElementById("submit").click();
        }
    </script>


Modify Telrik UI using jQuery

    $(document).ready(function() {

        var anof = $("a.fa:contains('Add new record')")
        anof.text("Add location");

        var anofr = $("a.fra:contains('Add new record')")
        anofr.text("Add man");
        anofr.mouseup(function(event) { setCookie("pos", event.pageY, 1); });
        var pos = getCookie("pos");
        if (!isNaN(pos)) scrollTo(0, pos);  // maintain scroll position
        setCookie("pos", "", 0);

        var url = window.location.href;
        if (url.indexOf("grd-mode=edit", 0) <= 0) {  // edit mode
            $("#save").click(function(e) {
                e.preventDefault();
            });
        }

         anof.click(function() {
            anof[0].href = removeParameter(anof[0].href, "grd-mode")
        });
        anofr.click(function() {
            anofr[0].href = removeParameter(anofr[0].href, "grd-mode")
        });
    }

    )

Friday, July 13, 2012

State Machine Desing Pattern






  #region SM definition and setup

    public interface IState
    {
        void EventSink(string eventData);
        void GoToNextState();
    }

    public class StateMachine
    {
        List _states ;
        public IState CurrentState { get; set; }
        public StateMachine()
        {
            _states = new List() { new State1(this), new State2(this)};  // omited Start and End State
        }

        public void SignalEvent(string infor)
        {
            if (infor == "Start")
            {
                CurrentState = (from _ in _states where _.GetType() == typeof(State1) select _).FirstOrDefault();
            }
            CurrentState.EventSink(infor);
        }

        internal void MoveState(IState st)
        {
            if (st.GetType() == typeof(State1))  // State2 would have move to End State
                CurrentState = (from _ in _states where _.GetType() == typeof(State2) select _).FirstOrDefault();
        }
    }

    #endregion


    #region Concrete States

    public class State1 : IState
    {
        StateMachine _sm;
        public State1(StateMachine sm)
        {
            _sm = sm;
        }
        public void EventSink(string eventData)
        {
            if (eventData == "RequiredInforType1Received")
            {
                Console.WriteLine("Processing Type1 Infor");
                Console.WriteLine("Passed, move to state2");
                GoToNextState();
            }
        }

        public void GoToNextState()
        {
            _sm.MoveState(this);
        } 
  
    }


    public class State2 : IState
    {
        StateMachine _sm;
        public State2(StateMachine sm)
        {
            _sm = sm;
        }
        public void EventSink(string eventData)
        {
            if (eventData == "RequiredInforType2Received")
            {
                Console.WriteLine("Processing Type2 Infor");
                Console.WriteLine("Passed, move to end state");
                GoToNextState();
            }
        }

        public void GoToNextState()
        {
            _sm.MoveState(this);
        }
    }

    #endregion

        static void Main(string[] args)
        {
            StateMachine sm = new StateMachine();
            sm.SignalEvent("Start");
            sm.SignalEvent("RequiredInforType1Received");
            sm.SignalEvent("RequiredInforType12Received");
            
            Console.ReadKey();
        }

Wednesday, July 4, 2012

IoC inject data into DropDownListFor

  DropDownListFor(m=>m.Name, ViewData["TheList"] requires repeatedly build ViewData. AutoFac IoCContainer Dependency Injection Could be used to avoid duplicating these code:

(1) We need to build Referenc List Types so we can resolve a Generic Type for IoC (i.e we cannot use Enum)
(2) Dependency Inject will inject a Repository IReferenceListRepository
(3) The generic Type SelectionList  must be able to render a list of SelectItem to feed into DropDownListFor base(LinqExpression, IEnumeralb)
(4) DropDownListFor Extension can now  build a generic type using type input param

    #region Reference List types

    public class USStatesRefList : ReferenceListType { }
    public class ApppealStatusesRefList : ReferenceListType { }
    public class EscalationToRefList : ReferenceListType { }

    public class ReferenceListType
    {
        public int Id { get; set; }
        public string Description { get; set; }
        public string ShortName { get; set; }
    }

    #endregion

  #region Ref Data Repository

    public interface IReferenceListRepository
    {
        IEnumerable<T> All<T>();
    }

    public class ReferenceListRepository : IReferenceListRepository
    {
        public IEnumerable<T> All()
        {
            // TODO; Build List from Database or RavenDB
            if (typeof(T)==typeof(USStatesRefList))
            {
              List<USStatesRefList> list= new List<USStatesRefList>() { new USStatesRefList() { Id=1, ShortName="MA", Description="MASS"}, new USStatesRefList() {Id=2, ShortName="NY",Description="Empire State"}};
              return (IEnumerable <T> ) list.AsEnumerable();
            }
            return default(IEnumerable<T>);
        }
    }
    #endregion

  #region Selection List -- can fill dropdown

    public class SelectionList<T> : IReferenceListRenderer where T : ReferenceListType
    {
       
        IEnumerable<T> _All { get;  set; }

       // Repository get injected here
        public SelectionList(IReferenceListRepository repository)
        { 
           _All = repository.All<T>();
        }

        public List<SelectListItem> RenderList(IConvertible value)
        {
            return (from p in _All
                   select
                       new SelectListItem
                       {
                           Value = null, // p.Id.ToString(),  DropDownList mal function if Value get set
                           Text =p.ShortName,// string.Format("{0} ({1})", p.Description, p.Id),
                           Selected =ValueEqual(p,value)
                       }).ToList();
        }

        public bool ValueEqual(ReferenceListType p, IConvertible value)
        {
            // For selection List, shortname matching ToString() is the only valid case
            return p.ShortName == Convert.ToString(value);
        }
    }

    public interface IReferenceListRenderer
    {
        List<SelectListItem> RenderList(IConvertible value);
    }

    #endregion


   #region Drop Down List  without using ViewData

    public static class DropDownListExtensions
    {
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> h,
                                                                       Expression<Func<TModel, TProperty>> expression,
                                                                       Type listType) where TProperty : IConvertible
        {

            var property = expression.Compile()(h.ViewData.Model);

            var SelectionListT = typeof(SelectionList<>).MakeGenericType(listType);
            var listR = DependencyResolver.Current.GetService(SelectionListT) as IReferenceListRenderer;
           List<SelectListItem> list = listR.RenderList(property);
            return h.DropDownListFor(expression,list );
        }
    }

    #endregion

@Html.DropDownListFor(m => m.Name, typeof(USStatesRefList));

Boiler Template code to hook up IoC

 protected void Application_Start()
        {
      var builder = new ContainerBuilder();
            builder.RegisterControllers(typeof(MvcApplication).Assembly);//Assembly.GetExecutingAssembly());
            builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
            builder.RegisterModule(new ApplicationModule());
            
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

   public class ApplicationModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
           // builder.RegisterInstance<ILog>(LogManager.GetLogger("TheInstance"));
            builder.RegisterType<ReferenceListRepository>().As<IReferenceListRepository>().InstancePerLifetimeScope();
            builder.RegisterGeneric(typeof(SelectionList<>)).SingleInstance();
           
        }


Monday, July 2, 2012

Using AutoFac IocContainer to inject Log4Net into MVC3

Nugget AutoFac, AutoFac.MVC3 and Log4Net into a MVC3 project

Create a Module to register

    public class ApplicationModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
           // builder.RegisterInstance(LogManager.GetLogger("TheInstance"));
           
        }
        protected override void AttachToComponentRegistration(Autofac.Core.IComponentRegistry componentRegistry, Autofac.Core.IComponentRegistration registration)
        {
           
            registration.Preparing += registration_Preparing;
        }

        static void registration_Preparing(object sender, Autofac.Core.PreparingEventArgs e)
        {
            var t = e.Component.Activator.LimitType;
            e.Parameters = e.Parameters.Union(
                new[]
                {
                                new ResolvedParameter((p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(t))  
                }
                );
        }
    }



Create Container, Register, Build and setResolver


       protected void Application_Start()
        {
           ...

            var builder = new ContainerBuilder();
            builder.RegisterControllers(typeof(MvcApplication).Assembly);//Assembly.GetExecutingAssembly());
            builder.RegisterModule(new ApplicationModule());
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }

Inject into COnstructor

  public class HomeController : Controller
    {

        public HomeController(ILog log)
        {

Thursday, June 28, 2012

MVC3 Log4Net Async and Customized Logging

Setup log4net in Web.Config is straight forward. Need to write Extension of ILog adding Task for Non-blocking Database write.

Web.Config

 <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler"/>
  </configSections>

  <log4net debug="false">

    <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
 <bufferSize value="1" />
        <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <!--<connectionString value="Data Source=Pentium22;Initial Catalog=db;Integrated Security=True" />-->
      <connectionString value="Data Source=Pentium22;Initial Catalog=db;User ID=sa;Password=xxxxxx;" />
        <!--<commandText value="INSERT INTO LogMVC3 ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />-->
      <commandText value="INSERT INTO LogMVC3A ([Date],[Message]) VALUES (@log_date, @message)" />
        <parameter>
          <parameterName value="@log_date" />
          <dbType value="DateTime" />
          <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
        </parameter>
        <parameter>
          <parameterName value="@thread" />
          <dbType value="String" />
          <size value="255" />
          <layout type="log4net.Layout.PatternLayout" value="%thread" />
        </parameter>
        <parameter>
          <parameterName value="@log_level" />
          <dbType value="String" />
          <size value="50" />
          <layout type="log4net.Layout.PatternLayout" value="%level" />
        </parameter>
        <parameter>
          <parameterName value="@logger" />
          <dbType value="String" />
          <size value="255" />
          <layout type="log4net.Layout.PatternLayout" value="%logger" />
        </parameter>
        <parameter>
          <parameterName value="@message" />
          <dbType value="String" />
          <size value="4000" />
          <layout type="log4net.Layout.PatternLayout" value="%message" />
        </parameter>
      </appender>
      <root>
        <level value="All"/>
        <appender-ref ref="AdoNetAppender_SqlServer"/>
      </root>
 
  </log4net>

Global.asax

        protected void Application_Start()
        {
            ...
            log4net.Config.XmlConfigurator.Configure();
        }
Note that for console app use [assembly: log4net.Config.XmlConfigurator(Watch = true)] 
Extension for ILog:

    public static class Class1
    {
        public static void Info2(this ILog log, object Message)
        {
            Task.Factory.StartNew(() =>
                {
                    log.Info(Message);
                    Thread.Sleep(5000);

                });
        }
    }

Logging anywhere w/o blocking:

    public static class Class1
    {
        public static void Info2(this ILog log, object Message)
        {
            Task.Factory.StartNew(() =>
                {
                    log.Info(Message);
                    Thread.Sleep(5000);

                });
        }

        public static void Audit2(this ILog log, object auditData)
        {
            Task.Factory.StartNew(() =>
            {
                AuditDataWrapper adw = new AuditDataWrapper() { AuditData = auditData };
                log.Info(adw);
                Thread.Sleep(5000);

            });
        }

    }
    public class AuditDataWrapper
    {
        public object AuditData { get; set; }
    }

Note:

root/level/value can be 
OFF FATAL ERROR WARN INFO DEBUG ALL

bufferSize=1 means immediate write to DB, no delay/caching
Reference:

http://basquang.wordpress.com/2011/08/26/logging-using-log4net-in-asp-net-mvc-3/


Customization -AuditData Pattern Converter

    public class AuditDataPatternLayoutConverter : PatternLayoutConverter
    {
        protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent)
        {
            object obj = loggingEvent.MessageObject;
            Type t = obj.GetType();
            if (loggingEvent.Level != log4net.Core.Level.Info || t != typeof(AuditDataWrapper)) return;

            AuditDataWrapper adw = obj as AuditDataWrapper;
             if (adw.AuditData==null) return;
             XmlSerializer ser = new XmlSerializer(adw.AuditData.GetType());
                
                StringWriter sw = new StringWriter();
               
                try
                {
                    ser.Serialize(sw, adw.AuditData);
                    sw.Flush();
                    writer.Write(sw.ToString());
                }
                catch
                {
                    string dump = DumpProperties(adw.AuditData, adw.AuditData.GetType());
                   writer.Write(dump);
                }
                
            
        }

        string DumpProperties(object obj, Type t)
        {
            PropertyInfo[] pi = t.GetProperties(); 
            StringBuilder sb = new StringBuilder();
            foreach (PropertyInfo p in pi) 
                 sb.Append(p.Name + " :" + p.GetValue(obj, null) + "\r\n"); 

           return sb.ToString();
        }


    }

      <parameter>
        <parameterName value="@auditdata" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <converter>
            <name value="auditdata" />
             <type value="MvcApplication3.AuditDataPatternLayoutConverter" />
          </converter>
          <conversionPattern value="%auditdata" />
        </layout>
      </parameter>

// Can put in any type of data into Audit

            log.Audit2(new TestData()
            {
                Name = "John",
                Age = 90,
                id = WindowsIdentity.GetCurrent(),
                Children = new List<TestData>() { new TestData() { Name = "Doe", Age = 12 }, new TestData() { Name = "Mat", Age = 9 } }
            });

    public class TestData
    {
        [System.Xml.Serialization.XmlIgnore]
        public WindowsIdentity id { get; set; }
        public string  Name { get; set; }
        public int Age { get; set; }
        public List<TestData> Children { get; set; }
    }



Customization -existing Log4Net converter

<commandText value="INSERT INTO LogMVC3 ([Date],[Thread],[Level],[Logger],[Message],[StackTrace],[AuditData],[UserName]) VALUES (@log_date, @thread, @log_level, @logger,@Message, @stacktrace,@auditdata,@username)" />


     <parameter>
        <parameterName value="@stacktrace" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value="%exception" />
      </parameter>
      <parameter>
        <parameterName value="@username" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value="%username" />
      </parameter>

%appdomain
%date 
%exception
%file
%identity  //slow
%level
%line 
%location 
%logger
%method
%message 
%newline
%timestamp
%type
%username  //slow
%utcdate

These can be used to format message:
     <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value=" %timestamp [%thread] %-5level %logger{2} %ndc - %message%newline" />
      </parameter>

Thursday, June 21, 2012

Asset Pricing Model for simulation

There are two type of Pricing Model: Stochastic for Growth, Factor for Mean Reversion. In both case mu for $ return or % return or factors can be observed and used in Simulation

% google get_hist_stock_data.m
[hist_date, hist_high, hist_low, hist_open, hist_close, hist_vol] =get_hist_stock_data('AAPL','2010');
R_dollar=hist_close(2:end)-hist_close(1:end-1);
R_pct=R_dollar./hist_close(1:end-1);

% $ return Random Walk
dT=1; %daily
mu=mean(R_dollar);
sigma=std(R_dollar);
St=zeros(100,1);
St(1)=560;

for i=1:1:100
    St(i+1)=St(i)+mu+sigma*sqrt(dT)*normrnd(0,1);
end 
f1=figure(1);
set(f1,'name','$ return Random Walk');
plot(0:100,St);

% % return Ramdom Walk
dT=1; %daily
mu=mean(R_pct);
sigma=std(R_pct);
St=zeros(100,1);
St(1)=560;
for i=1:1:100
    St(i+1)=St(i)*exp((mu-sigma^2/2)*dT+sigma*sqrt(dT)*normrnd(0,1));
end 
f2=figure(2);
set(f2,'name','% return Random Walk');
plot(0:100,St);

% % return Mean Reversion Factor Model
dT=1; %daily
mu=mean(R_dollar);
sigma=std(R_dollar);
St=zeros(100,1);
St(1)=560;

p=polyfit(hist_close(2:end),R_pct,1)



% google get_hist_stock_data.m
[hist_date, hist_high, hist_low, hist_open, hist_close, hist_vol] =get_hist_stock_data('USO','2010');
R_dollar=hist_close(2:end)-hist_close(1:end-1);
R_pct=R_dollar./hist_close(1:end-1);

days=100
% $ return Mean Reversion Factor Model
dT=1; %daily
mu=mean(hist_close);
sigma=std(hist_close);
St=zeros(days,1);
St(1)=hist_close(end);

b=regress(R_dollar,hist_close(2:end));
b  
k=-b;

for i=1:1:days
    St(i+1)=St(i)+k*(mu-St(i))+sigma*normrnd(0,1);
end 
f1=figure(1);
set(f1,'name','$ return Mean Reversion Factor Model');
plot(0:days,St);


% % return Mean Reversion Factor Model---see MR Factor Model

Sunday, June 17, 2012

WPF 3D Plot -- Multivariate Normal

Multivariate Normal distribution is represented by an array of 3d vector associated PDF:

mu=[2 3 5];
sigma=[1,1.5,.5;1.5 3, 0.5;0.5,0.5,2];  %covariance
r=mvnrnd(mu,sigma,100);

p=mvnpdf(r,mu,sigma);
[r,p]  

We can plot mvnrnd in WPF Helix 3D Viewbox using pdf as "Density Material"

<Window>
....
       <ht:HelixViewport3D ItemsSource="{Binding Objects}"  ShowCoordinateSystem="True"  ShowCameraInfo="True"  />

</Window>

 public ObservableCollection<Visual3D> Objects { get; set; }

For some reason I have to build 3D plot by ThreadPool. Calling directly from ctor does not work.
            t = Task.Factory.StartNew(() =>
            {
            }).ContinueWith((t0) =>
            {
                if (Objects.Count == 0)
                    Objects.Add(new DefaultLights());
                Material m = GetData();
                List<Point3DWithDensity> list = Data3D.GetSamplePoints();
                 maxDensity = (from _ in list select _.Density).Max();
                 minDensity = (from _ in list select _.Density).Min();
                foreach( var v in list)
                {
                    BoxVisual3D sp = new BoxVisual3D() { Center = v.Point3D, Height = v.Density, Width = v.Density, Length = v.Density, Material = GetDensityMaterial(v.Density, v.Point3D) };
                 //   SphereVisual3D sp = new SphereVisual3D { Center = v.Point3D, Radius = v.Density, Material = GetDensityMaterial(v.Density, v.Point3D) };
               
                    Objects.Add(sp);
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());


        double maxDensity;
        double minDensity;
        private Material GetDensityMaterial(double d, Point3D p)
        {
            DiffuseMaterial m = new DiffuseMaterial();
            int i = (int)Math.Round(((maxDensity - d) * 1.0 + (d - minDensity) * 10) / (maxDensity - minDensity));
            SolidColorBrush scb = new SolidColorBrush(GetColor(i)); 
            VisualBrush vb = new VisualBrush();
            TextBlock tb = new TextBlock { Text = "(" + p.X.ToString() + "," + p.Y.ToString() + "," + p.Z.ToString() + ")", Background = scb };
           
            vb.Visual = tb;
            m.Brush = vb;
            return m;
        }

    public class Data3D
    {
        public static List<Point3DWithDensity> GetSamplePoints()
        {
            #region Raw Data

            string rawDataFromMATLAB = @"
    2.3631    4.9997    4.8456    0.0129
         ..................
    1.9576    3.5687    1.9473    0.0040
    2.7463    3.6281    4.7240    0.0300";

            #endregion

            List<Point3DWithDensity> list = new List<Point3DWithDensity>();
            string[] pointData = ReplaceMultipleSpace(rawDataFromMATLAB).Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string s in pointData)
            {
               string[] xyz= s.Trim().Split(' ');
               list.Add(new Point3DWithDensity()
                {
                    Point3D = new Point3D()
                    {
                        X = Convert.ToDouble(xyz[0].Trim()),
                        Y = Convert.ToDouble(xyz[1].Trim()),
                        Z = Convert.ToDouble(xyz[2].Trim())
                    },
                    Density=Convert.ToDouble(xyz[3].Trim())
                });
            }
            return list;
        }
        static string ReplaceMultipleSpace(string s)
        {
            RegexOptions options = RegexOptions.None; 
            Regex regex = new Regex(@"[ ]{2,}", options);     
            return regex.Replace(s, @" "); 
        }
    }
    public class Point3DWithDensity 
    {
        public Point3D Point3D { get; set; }
        public double Density { get; set; }
    }

        public static Color GetColor(int value) { 
            int startIndex = (value / 10) * 10; 
            int endIndex = startIndex + 10;
            Color startColor = Colors.Red;
            Color endColor = Colors.Blue;
            float weight = (value - startIndex) / (float)(endIndex - startIndex);
          
            return Color.FromArgb(255,
                (byte)Math.Round(startColor.R * (1 - weight) + endColor.R * weight), 
                (byte)Math.Round(startColor.G * (1 - weight) + endColor.G * weight), 
                (byte)Math.Round(startColor.B * (1 - weight) + endColor.B * weight)); 
        } 

Thursday, June 14, 2012

WPF Primitive Element could still uses Sofware Rendering

The following simple Animation strangely still uses swIRT shown in Perforator.
It turns out that WPF Rendering pipe need to rasterize DrawingBrush in software and hand over to GPU. And the only solution is to use RenderingOption,CachingHint on DrawingBrush

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <DrawingBrush x:Key="MyBlueGridBrushResource" Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile"
                      RenderOptions.CachingHint="Cache"
                      RenderOptions.CacheInvalidationThresholdMaximum="1000" RenderOptions.CacheInvalidationThresholdMinimum="0.5">
            <DrawingBrush.Drawing>
                <DrawingGroup>
                    <DrawingGroup.Children>
                        <GeometryDrawing Brush="White">
                            <GeometryDrawing.Geometry>
                                <RectangleGeometry Rect="0,0,1,1" />
                            </GeometryDrawing.Geometry>
                        </GeometryDrawing>
                      
                    </DrawingGroup.Children>
                </DrawingGroup>
            </DrawingBrush.Drawing>
        </DrawingBrush>
    </Window.Resources>

    <DockPanel Margin="10">
        <Canvas Width="250" Height="250"  Background="{StaticResource MyBlueGridBrushResource}">
            <Rectangle
            Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2"
            Canvas.Left="100" Canvas.Top="100">
                <Rectangle.RenderTransform>
                    <ScaleTransform x:Name="MyAnimatedScaleTransform" CenterX="25" CenterY="25" ScaleX="1" ScaleY="1" />
                </Rectangle.RenderTransform>
            </Rectangle>
            <Rectangle Height="50" Width="50" Stroke="#99000000"
            StrokeDashArray="4,1" StrokeThickness="2"
            Canvas.Left="100" Canvas.Top="100" />
        </Canvas>
        <DockPanel  HorizontalAlignment="Center" VerticalAlignment="Bottom"
        Margin="10">
            <Button Name="startButton" Margin="0,0,2,0">Start</Button>
            <DockPanel.Triggers>
                <EventTrigger SourceName="startButton" RoutedEvent="Button.Click">
                    <BeginStoryboard Name="myBeginStoryboard">
                        <Storyboard>
                            <DoubleAnimation 
                  Storyboard.TargetName="MyAnimatedScaleTransform" 
                  Storyboard.TargetProperty="ScaleX" 
                  From="0" To="5" Duration="0:0:2" />
                            <DoubleAnimation 
                  Storyboard.TargetName="MyAnimatedScaleTransform" 
                  Storyboard.TargetProperty="ScaleY" 
                  From="0" To="5" Duration="0:0:2" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </DockPanel.Triggers>
        </DockPanel>
    </DockPanel>
</Window>

Sunday, June 3, 2012

AppFabric 1.1 host WCF multi-binding and Json Data

We can configure WCF services with Multiple EndPoints. To return Json, the following steps are needed:

(1) Change OperationContract using WebGet, Json and UriTemplate  --- note that input can only be string
        [WebGet(ResponseFormat=WebMessageFormat.Json, UriTemplate="Data/{value}")]
        [OperationContract]
        List GetData(string value);

(2) App.Config ==> Edit WCF config ==> Add webHttpBinding with Binding Behavior wedHttp
    <services>
      <service name="WcfServiceLibrary1.Service1">
        ...
   
        <endpoint address="jsonTest" behaviorConfiguration="NewBehavior0"
          binding="webHttpBinding" bindingConfiguration="" contract="WcfServiceLibrary1.IService1" />
      ...
    <behaviors>
      <endpointBehaviors>
        <behavior name="NewBehavior0">
          <webHttp />
        </behavior>
      </endpointBehaviors>

(3) Publish to AppFabric Site/App considering the following details:
     (3.1) Make sure WebDeploy (MSDeploy,VS2010SP1) update installed so that AppFabric has deploy menu and VS2010 WCF App has Package/publish tab
     (3.2) Note that We are using WCF Lib not app so publish to AppFabric rather than using package.
     (3.3) Edit binding to default WebSite to have net.tcp binding infor 808:* and net.pipe etc and create an App "mb" with "http,net.tcp,net.pipe"
           as enabled protocols.
     (3.4) Browse the app to get base address like http://localhost/mb/WcfServiceLibrary1.Service1.svc
           test http://[baseAddress]/jsonTest/Data/0 should get to Json Data (save to disk)
     (3.5) make sure net.tcp port and address match 808:* and uses App "mb" and use a WPF client to add Service Reference for testing. and we should
           see client config has all protocols.

Saturday, June 2, 2012

Style Trigger and DataTrigger

To style a simple Lisbox, we can trigger change of property by either looking at other property or data loaded


       <Style TargetType="{x:Type ListBoxItem}" >
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="true">
                    <Setter Property="Foreground" Value="Red" />
                </Trigger>
                <DataTrigger Binding="{Binding Path=Name}" Value="User 3">
                    <Setter Property="BorderBrush" Value="Black" />
                    <Setter Property="BorderThickness" Value="1" />
           ...
             list.Add(new User(){ Name="User 1"});
            list.Add(new User() { Name = "User 2" });
         
            listBox1.ItemsSource = list;

Thursday, May 31, 2012

Monday, May 28, 2012

WPF 3 D Coordinate System with A Camera: Example

Then we can map 2D Texture to 3D using MeshGeometry3D

       <Viewport3D>
            <Viewport3D.Camera>
                <PerspectiveCamera Position="-20,46,0" UpDirection="0,0,1" LookDirection="4,-10,0" NearPlaneDistance="0"/>
            ......
                    <GeometryModel3D.Geometry>
                      <MeshGeometry3D  Positions="-10,-10,-10  10,-10,-10  10,10,-10  -10,10,-10  -10,-10,10  -10,10,10"
                          TriangleIndices="0 2 3  0 1 2   0 4 3  4 5 3" 
                               TextureCoordinates="0,0  0,1  1,1  1,0" />

Saturday, May 26, 2012

Robust Optimization Through SOCP Duality

Future Pricing and MR factor model

MATLAB code

[hist_date, hist_high, hist_low, hist_open, hist_close, hist_vol] =get_hist_stock_data('SPX','2006');
Data=hist_close;
[n,nn] = size(Data);

R_dollar=hist_close(2:end)-hist_close(1:end-1);
R_pct=R_dollar./hist_close(1:end-1);

[b_int,nn,nn,nn,stats] = regress(R_pct,[ones(n-1,1),Data(1:(n-1),1)]); 

intercept = b_int(1);
slope = b_int(2);
if (slope > 0)
    error('Cannot use geometric mean reversion: pct chg=k*(mu-s)+sigma*dW requiring k>0)');
end

sigma = sqrt(stats(4));
k = -slope; 
mu = -intercept/slope;


days=20;
dT = 1; 

St=zeros(days,1);
St(1)=hist_close(end);

for i=1:1:days
    St(i+1)=St(i)+(k*(mu-St(i))+sigma*normrnd(0,1))*St(i);
end 

% future price dS/S = dLn(F(t))/dt *dt + signma*dW or
%              Ft-1=Ft*exp(-dS/S+signma*dW)
Ft=zeros(days,1);
Ft(end)=St(end);  
for i=days:-1:2
    chg =(St(i+1)-St(i))/St(i);
    Ft(i-1)=Ft(i)*exp(-chg+sigma*normrnd(0,1));
end 

f1=figure(1);
set(f1,'name','%-Return Mean Reversion Factor Model');
p=plot(0:days,St);
set(p,'color','red');
hold on;
p=plot(1:days,Ft);
hold off;


Friday, May 25, 2012

Sunday, April 22, 2012

Visitor Design Pattern


(1) IAccept will Accept any IVisitor, which include all object types in signature.
(2) All participating object types implement IAccept with boiler template code visit(this)
(3) Visitors are responsible to implement how to visit a type.

Benefit: Ensure new visitor must know how to visit all types, and these types does not
need to change to allow new visitors.






 

    #region IAccept Universal Visitor

    public interface IVisitor
    {
        // List the universe of objects
        void Visit(Swap sw);
        void Visit(Option o);
        void Visit(Bond b);
    }

    public interface IAccept
    {
        void Accept(IVisitor visitor);
    }

    #endregion

    #region Universal objects  Accept any Visitor(this) --boiler template code

    public class Swap : IAccept
    {
        public void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }
    }
    public class Option : IAccept
    {
        public void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }
    }
    public class Bond : IAccept
    {
        public void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }
    }

    #endregion

#region Risk Visitor -- must know how to visitor any objects

    public class RiskVisitor : IVisitor 
    {
        public void Visit(Swap sw)
        {
            Console.WriteLine("Special works related to Risk of SWAP");
        }

        public void Visit(Option o)
        {
            Console.WriteLine("Special works related to Risk of Option");  
        }

        public void Visit(Bond b)
        {
            Console.WriteLine("Special works related to Risk of Bond");
        }
    }

    #endregion

    #region Pricing Visitor -- must know how to visitor any objects

    public class PricingVisitor : IVisitor
    {
        public void Visit(Swap sw)
        {
            Console.WriteLine("Special works related to Pricing of SWAP");
        }

        public void Visit(Option o)
        {
            Console.WriteLine("Special works related to Pricing of Option");
        }

        public void Visit(Bond b)
        {
            Console.WriteLine("Special works related to Pricing of Bond");
        }
    }

   #endregion


            // (1)  each visitor visit object
            RiskVisitor rv = new RiskVisitor();
            rv.Visit(new Swap());
            rv.Visit(new Option());

            PricingVisitor pv = new PricingVisitor();
            pv.Visit(new Swap());
            pv.Visit(new Option());


            // (2) each object accept any visitor
            Swap sw = new Swap();
            sw.Accept(new RiskVisitor());
            Console.ReadLine();

Saturday, April 21, 2012

WPF Breadcrumb markup


                            <ListBox  Padding="0" DockPanel.Dock="Left"  VerticalAlignment="Center" x:Name="lbBreadCrumb" MinWidth="300" Background="Transparent" BorderThickness="0" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" SelectionChanged="ListBox_SelectionChanged">
                                <ListBox.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Margin="8,0,0,0" Orientation="Horizontal"></StackPanel>
                                    </ItemsPanelTemplate>
                                </ListBox.ItemsPanel>
                                <ListBox.ItemContainerStyle>
                                    <Style TargetType="{x:Type ListBoxItem}">
                                        <Setter Property="Background" Value="LightGray"/>
                                        <Setter Property="BorderBrush" Value="LightGray"/>
                                        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                                        <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                                        <Setter Property="Padding" Value="0"/>
                                        <Setter Property="SnapsToDevicePixels" Value="true"/>
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="ListBoxItem">
                                                    <DockPanel LastChildFill="True" Margin="-8,0,0,0">
                                                        <Path x:Name="ArrowTip" DockPanel.Dock="Left" Stroke="LightGray" Fill="LightGray" Data="F1 M 112,144L 104,144L 112,160L 104,176L 112,176" Stretch="Fill" Height="32" Width="12"  />
                                                        <Path x:Name="Arrow" DockPanel.Dock="Right" Stroke="LightGray" Fill="LightGray" Data="F1 M 168,144L 176,160L 168,176" Stretch="Fill" Height="32" Width="12"  />
                                                        <Border Name="Border" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Background="{TemplateBinding Background}" BorderBrush="LightGray" Padding="{TemplateBinding Padding}" BorderThickness="0,1,0,1" VerticalAlignment="Center" Margin="-1,0,-1,0" >
                                                            <ContentPresenter />
                                                        </Border>
                                                    </DockPanel>
                                                    <ControlTemplate.Triggers>
                                                        <Trigger Property="IsSelected" Value="true">
                                                            <Setter TargetName="Border" Property="Background" Value="Gray"/>
                                                            <Setter TargetName="Arrow" Property="Fill" Value="Gray"/>
                                                            <Setter TargetName="ArrowTip" Property="Fill" Value="Gray"/>
                                                        </Trigger>
                                                        <Trigger Property="IsEnabled" Value="false">
                                                            <Setter Property="Foreground" Value="Red"/>
                                                        </Trigger>
                                                    </ControlTemplate.Triggers>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </ListBox.ItemContainerStyle>
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <DataTemplate.Resources>
                                                <local:ContentToVisibilityConverter x:Key="c2vConverter" />
                                        </DataTemplate.Resources>
                                        <DockPanel VerticalAlignment="Center" Height="30">
                                            <Label DockPanel.Dock="Left" FontSize="8" Content="{Binding Name, FallbackValue=Tagname NA}" VerticalAlignment="Center" Name="lb"/>
                                            <Button  Width="20" Height="20" Background="#FF1D5BBA"  Margin="0" Style="{StaticResource GlassButton}" Visibility="{Binding ElementName=lb, Path=Content., Converter={StaticResource c2vConverter}}">
                                                <Image Width="15" Height="15" Source="images\refresh.png" ToolTip="Refresh Dashboard" MouseLeftButtonDown="RefreshImage_MouseLeftButtonDown" />
                                            </Button>
                                        </DockPanel>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>

Show WPF Form considering taskbar


     // Considering space for Taskbar at the bottom.
            MONITORINFO monitorInfo = new MONITORINFO();
            int MONITOR_DEFAULTTONEAREST = 0x00000001;
            System.IntPtr handle = (new WinInterop.WindowInteropHelper(this)).Handle;
            System.IntPtr monitor = MonitorFromWindow(handle, MONITOR_DEFAULTTONEAREST);
            GetMonitorInfo(monitor, monitorInfo);
            RECT rcWorkArea = monitorInfo.rcWork;
            RECT rcMonitorArea = monitorInfo.rcMonitor;

            M.Height = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);// SystemParameters.MaximizedPrimaryScreenHeight - 20;
            M.Width = SystemParameters.MaximizedPrimaryScreenWidth - 15;

            M.Top = 0; M.Left = 0;

        #region Win32 API

        [DllImport("user32")]
        internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);

        /// 
        /// 
        /// 
        [DllImport("User32")]
        internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

        #endregion

Saturday, March 24, 2012

Dynamic Programming Tree in MATLAB


function [x]=dynamicProgTree()
% states --oil reserve
x(1).rsrv=[600000];
x(2).rsrv=[500000 400000];
x(3).rsrv=[400000 300000 200000];
x(4).rsrv=[300000 200000 100000 0];

% Normal and Enhanced Pumping
% Value Onward at t=4 is 0 due to lease expiration
x(4).Vn=[0 0 0 0];
x(4).Ve=[0 0 0 0];
x(4).V=max(x(4).Vn,x(4).Ve);

% Value
% Onward=oilPrice*policy-multiplier*policy^1/reserve+discountedValueOnward
for i=1:3
   x(3).Vn(i)=40*100000- 1*100000^2/x(3).rsrv(i)+0.9*x(4).V(i);
   x(3).Ve(i)=40*200000- 20*200000^2/x(3).rsrv(i)+0.9*x(4).V(i+1);
end
% ValueOnward= Max (Norma, Enahnced)
x(3).V=max(x(3).Vn,x(3).Ve);

for i=1:2
   x(2).Vn(i)=30*100000- 1*100000^2/x(2).rsrv(i)+0.9*x(3).V(i);
   x(2).Ve(i)=30*200000- 20*200000^2/x(2).rsrv(i)+0.9*x(3).V(i+1);
end
x(2).V=max(x(2).Vn,x(2).Ve);

for i=1:1
   x(1).Vn(i)=45*100000- 1*100000^2/x(1).rsrv(i)+0.9*x(2).V(i);
   x(1).Ve(i)=45*200000- 20*200000^2/x(1).rsrv(i)+0.9*x(2).V(i+1);
end
x(1).V=max(x(1).Vn,x(1).Ve);
end


Wednesday, February 29, 2012

Deep Copy Helper


       public static T DeepCopy<T>(T obj)
        {
            if (obj == null)
                throw new ArgumentNullException("Object cannot be null");
            return (T)Process(obj);
        }

        static object Process(object obj)
        {
            if (obj == null)
                return null;
            Type type = obj.GetType();
            if (type.IsValueType || type == typeof(string))
            {
                return obj;
            }
            else if (type.IsArray)
            {
                Type elementType = Type.GetType(
                     type.FullName.Replace("[]", string.Empty));
                var array = obj as Array;
                Array copied = Array.CreateInstance(elementType, array.Length);
                for (int i = 0; i < array.Length; i++)
                {
                    copied.SetValue(Process(array.GetValue(i)), i);
                }
                return Convert.ChangeType(copied, obj.GetType());
            }
            else if (type.IsClass)
            {
                object toret = Activator.CreateInstance(obj.GetType());
                //FieldInfo[] fields = type.GetFields(BindingFlags.Public |
                //            BindingFlags.NonPublic | BindingFlags.Instance);
                FieldInfo[] fields = GetAllFields(type).ToArray();
                foreach (FieldInfo field in fields)
                {
                    object fieldValue = field.GetValue(obj);
                    if (fieldValue == null)
                        continue;
                    field.SetValue(toret, Process(fieldValue));
                }
                return toret;
            }
            else
            {
                return null;
                //throw new ArgumentException("Unknown type");
            }
        }

        public static IEnumerable<FieldInfo> GetAllFields(Type t) { 
            if (t == null)         return Enumerable.Empty<FieldInfo>();
            BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance
                | BindingFlags.DeclaredOnly; 

            return t.GetFields(flags).Union(GetAllFields(t.BaseType)); 
        } 

Note that If we restrict to Serializable then using Memory Stream can deep copy

   class Program
    {
        static void Main(string[] args)
        {
            Outside o = new Outside() { Data = new Inside() { Name = "n1", Price = 199 } };

            Outside o_sc = o.ShadowCopy;
            o_sc.Data.Name = "Changed"; // change o as well since Shadow copy reference
            Outside o_dc = o.DeepCopy;
            o_dc.Data.Name = "Reset"; // not affect o
        }
    }

    [Serializable]
    public class Outside
    {
        public Inside Data { get; set; }
        public Outside ShadowCopy { get { return  MemberwiseClone() as Outside ; } }
        public Outside DeepCopy
        {
            get
            {
                MemoryStream m = new MemoryStream();
                BinaryFormatter b = new BinaryFormatter();
                b.Serialize(m, this);
                m.Position = 0;
                return b.Deserialize(m) as Outside;
            }
        }
        
    }

    [Serializable]
    public class Inside
    {
        public string Name { get; set; }
        public double Price { get; set; }
    }

Sunday, February 19, 2012

HTML5 Canvas API


<canvas w h id="cv"/>

var ctx=document.getElementById("cv").getContext('2d');

Path Drawing:
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x1,y1);
ctx.closePath();

Fill
ctx.fillRec();
ctx.fillStyle='rgba(0,0,0,0.2)'; alpha 0.2 for black.

Mouse move vs. Touch move
cv.onMouseMove= function Draw(e) {..}
document.addEventListener('touchmove', function (e) { });

e.preventDefault(); not allow Ipad Giggle.
e.targetTouches[0].pageX;
ctx.transform (matrix+d);
cx.scale(60%);




Tuesday, January 31, 2012

Correlated Action ComboBox Behavior


<UserControl xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:loc="clr-namespace:TestCorrTextBoxCustBehavior">

       <ComboBox Height="23" HorizontalAlignment="Left" Margin="12,48,0,0" Name="cb1" VerticalAlignment="Top" Width="120" >
            <i:Interaction.Behaviors>
                <loc:CorrelatedActionComboBoxBehavior SourceRegularExpression="['Basket Swap'|'CDS']" SourceTriggerType="RegExpression"  TargetControlId="lb1" TargetActionType="SetValue" TargetValue="2"/>
            </i:Interaction.Behaviors>
            <ComboBoxItem>1</ComboBoxItem>
            <ComboBoxItem>Basket Swap</ComboBoxItem>
            <ComboBoxItem>CDS</ComboBoxItem>
        </ComboBox>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="268,48,0,0" Name="textBox2"  VerticalAlignment="Top" Width="120" />
        <ListBox Name="lb1" Width="100" Height="200" Margin="355,91,48,20">
            <ListBoxItem>1</ListBoxItem>
            <ListBoxItem>2</ListBoxItem>
            <ListBoxItem>3</ListBoxItem>
        </ListBox>



   public class CorrelatedActionComboBoxBehavior : Behavior</ComboBox>
    {

        public SourceTriggerType SourceTriggerType { get; set; }
        public string SourceRegularExpression { get; set; }
        public string TargetControlId { get; set; }
        public TargetActionType TargetActionType { get; set; }
        public string TargetValue { get; set; }
       
        protected override void OnAttached()
        {
            if (!(AssociatedObject is ComboBox)) return;
            object obj = AssociatedObject.Parent;
            Control mw = ((System.Windows.Controls.Panel)(obj)).Parent as Window;
            if (mw==null)
             mw = ((System.Windows.Controls.Panel)(obj)).Parent as Control;
            if (mw == null) return;

            AssociatedObject.DropDownClosed += (sender, e) =>
                { 
                    ComboBox cb = AssociatedObject as ComboBox;
                    if (SourceTriggerType == SourceTriggerType.RegExpression)
                    {
                        Regex r = new Regex(SourceRegularExpression);

                        Control c = FindChild(mw, TargetControlId);
                        c.IsEnabled = true;
                        if (r.IsMatch(cb.Text) )
                        {
                           if ( TargetActionType== TargetActionType.Disable ) c.IsEnabled = false;
                           if (TargetActionType == TargetActionType.SetValue)
                           {
                               ListBox lb = c as ListBox;
                               if (lb != null && TargetValue!="") SetListBoxValue(lb, TargetValue);
                           }

                        }
                    }
                };
        }

        private void SetListBoxValue(ListBox lb, string p)
        {
            for(int i=0;i< lb.Items.Count;i++)
            {
                if ((lb.Items[i] as ListBoxItem).Content.ToString()  == p) lb.SelectedIndex = i;
            }
        }

        public static T FindChild(DependencyObject parent, string childName)    where T : DependencyObject {      
            // Confirm parent and childName are valid.   
            if (parent == null) return null;    
            T foundChild = null;    
            int childrenCount = VisualTreeHelper.GetChildrenCount(parent);  
            for (int i = 0; i < childrenCount; i++)   {   
                var child = VisualTreeHelper.GetChild(parent, i);    
                // If the child is not of the request child type child   
                T childType = child as T;    
                if (childType == null)     {     
                    // recursively drill down the tree    
                    foundChild = FindChild(child, childName);     
                    // If the child is found, break so we do not overwrite the found child.     
                    if (foundChild != null) break;     }    
                else if (!string.IsNullOrEmpty(childName))     {   
                    var frameworkElement = child as FrameworkElement;     
                    // If the child's name is set for search     
                    if (frameworkElement != null && frameworkElement.Name == childName)       {    
                        // if the child's name is of the request name       
                        foundChild = (T)child;         break;       }     }  
                else     {       
                    // child element found.      
                    foundChild = (T)child;       break;     }   }  
            return foundChild; } 

     }

    public enum SourceTriggerType
    {
        RegExpression
    }

    public enum TargetActionType
    {
        Disable,
        SetValue
    }

Monday, January 30, 2012

WPF Custom Behavior

(1) Behavior is a gneric type <>, non-generic one has no public ctor
(2)  Need System.Interactivity.Dll from Blend SDK or MVVM light donwload

<Window x:Class="TestCustomBehavior.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:local="clr-namespace:TestCustomBehavior"
         >
    <Grid>
        <TextBlock Background="LightBlue" Height="23" HorizontalAlignment="Left" Margin="134,140,0,0" Name="textBlock1" Text="Drag Me Around" VerticalAlignment="Top" >
            <i:Interaction.Behaviors>
                <local:DragBehavior></local:DragBehavior>
            </i:Interaction.Behaviors>
        </TextBlock>
    </Grid>
</Window>



namespace TestCustomBehavior
{
    public class DragBehavior : Behavior<UIElement>
    {
        Point startPosMouse, startPosElement; int i = 0;
        TranslateTransform trans = new TranslateTransform();
        protected override void OnAttached()
        {
            Window parent = Application.Current.MainWindow;
            AssociatedObject.RenderTransform = trans;
            AssociatedObject.MouseLeftButtonDown += (sender, e) =>
                {
                    if (i == 0)
                    {
                        startPosElement = AssociatedObject.TranslatePoint(new Point(), parent); i = 1;
                    }
                    startPosMouse = e.GetPosition(parent);
                    AssociatedObject.CaptureMouse();
                };
            AssociatedObject.MouseLeftButtonUp += (sender, e) =>
                {
                    AssociatedObject.ReleaseMouseCapture();
                };

            AssociatedObject.MouseMove += (sender, e) =>
                {
                    Vector diff = e.GetPosition(parent) - startPosElement;
                    if (AssociatedObject.IsMouseCaptured)
                    {
                        trans.X= diff.X;
                        trans.Y = diff.Y;
                    }

                };
        }
    }
}

Sunday, January 29, 2012

WPF Printing using FixedDcoument


Print Preview Popup as FixedDocument

(1) PageContent will has Compiler Error but can stil render with FixedPage---Known Defect of WPF.
(2) Fixed document will has toolbar shown by WPF, no coded needed. So this is simplest printing

<Window x:Class="TestWPFPrinting.PrintPreview"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="PrintPreview" Height="300" Width="300">
    <FixedDocument Name="customerReport">

        <PageContent>

            <FixedPage>
                <Label FontSize="20" Margin="100,20,0,0">REPORT</Label>
                <ListView  BorderThickness="0" Margin="50,100,0,0" FontSize="14" Width="Auto" Height="Auto" ItemsSource="{Binding}">
                    <ListView.View>
                        <GridView x:Name="gridReport">

                            <GridViewColumn Width="200" Header="FirstName" DisplayMemberBinding="{Binding Path=FirstName}">

                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <Label/>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                            <GridViewColumn Width="200" Header="LastName" DisplayMemberBinding="{Binding Path=LastName}">
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <Label/>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                        </GridView>
                    </ListView.View>
                </ListView>

            </FixedPage>

        </PageContent>
    </FixedDocument>
</Window>

Bind to Data
   public partial class PrintPreview : Window
    {
        private List<Customer> _customers;
        public PrintPreview(List<Customer> customers) 
        {
            InitializeComponent();
            _customers = customers;
            // generate report 
            this.DataContext = _customers; 
        }
    }

    public class Customer
    {
        private string _firstName;
        private string _lastName;

        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }

        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; }
        }
    }

Main Form
       private void button1_Click(object sender, RoutedEventArgs e)
        {

            List<Customer> customers = new List<Customer>();

            for (int i = 1; i <= 200; i++)
            {
                Customer customer = new Customer();
                customer.FirstName = "FirstName " + i;
                customer.LastName = "LastName " + i;
                customers.Add(customer);
            }
            PrintPreview w = new PrintPreview(customers);
            w.Show();