Blog Archive

Thursday, November 14, 2013

Context Menu style must be applied to MenuItem Level by ItemContainerStyle to avoid delegate command bind to the same target



Context Menu style must be applied to MenuItem Level by ItemContainerStyle

Using TextBox.ContextMenu will create two instances of the style s1 so it will not bind only one textbox by Multiple binding.

        <TextBox HorizontalAlignment="Left" Height="30" Margin="10,554,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="211" Name="tb1" >
            <TextBox.ContextMenu>
                <ContextMenu ItemsSource="{Binding Mode=OneWay,Path=SelectorData}" ItemContainerStyle="{StaticResource s1}"></ContextMenu>
            </TextBox.ContextMenu>
        </TextBox>

            <Style TargetType="MenuItem" x:Key="s1">
                <Setter Property="ItemsSource" Value="{Binding SubSelectorData}"></Setter>
                <Setter Property="Header" Value="{Binding Name}"></Setter>
                <Setter Property="Tag" Value="{Binding ReturnValue}"></Setter>
                <Setter Property="Command" Value="{Binding SelectorCommand}"></Setter>
                <Setter Property="CommandParameter">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource multiSenderTarget2CmdParamConv}">
                            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type TextBox}}"></Binding>
                            <Binding RelativeSource="{RelativeSource Self}"></Binding>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
           
            </Style>


public List<SelectorData> SelectorData { get; set; }

            SelectorService svc = new SelectorService();
            svc.SelectorCommandAll = new DelegateCommand<object>((p) =>
            {
                Tuple<object, object> t = p as Tuple<object, object>;
                TextBox tb = t.Item1 as TextBox;
                MenuItem mi = t.Item2 as MenuItem;
                tb.Text = mi.Tag.ToString() + ";" + mi.Header.ToString();

            });

    public class MutipleSenderTargetToCommandParameterConverter : System.Windows.Data.IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (values.Length == 1) return new Tuple<object>(values[0]);
            if (values.Length == 2) return new Tuple<object, object>(values[0], values[1]);


        <Style x:Key="ssOnlyOneInstanceNotWorking" TargetType="{x:Type TextBox}" >
            <Setter Property="TextBox.ContextMenu" >
                <Setter.Value>
                    <ContextMenu ItemsSource="{Binding Mode=OneWay,Path=SelectorData}" ItemContainerStyle="{StaticResource s1}"></ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>


    public class SelectorData
    {
        public string Name { get; set; }
        public List<SelectorData> SubSelectorData { get; set; }
        public bool HasSubSelectorData { get; set; }
        public int Level { get; set; }
        public DelegateCommand<object> SelectorCommand { get; set; }
        public string ReturnValue { get; set; }
    }

Thursday, September 26, 2013

Self Arrange Top Windows

WPF Desktop App can Popup multiple full size windows randomly and confuse users. So it is useful to create a list storing these windows and arrange their display as One Full size with all other as thumbnail hanging to the side.


The following code implement what is shown in the screen shot. Note this assume one dispatcher due to threading issues. i.e all windows must pop up from on dispatcher.

Code for a window self arrange:

using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace WpfApplication1 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window2 : Window { #region declaration public IObservable<System.Reactive.EventPattern<EventArgs>> WindowLocationChangedRxEventArgs { get; set; } public IObservable<System.Reactive.EventPattern<MouseButtonEventArgs>> WindowMouseDownRxEventArgs { get; set; } public IObservable<System.Reactive.EventPattern<MouseEventArgs>> HeaderPreviewMouseMoveRxEventArgs { get; set; } public bool SwitchInProgress { get; set; } public static SortedList<DateTime, Window2> TopWindowList { get; set; } public Guid ID { get; set; } public DateTime AddedAt { get; set; } public static Point LocationOfArrangement { get; set; } #endregion #region Contructor public Window2() { InitializeComponent(); WindowStyle = System.Windows.WindowStyle.None; ResizeMode = System.Windows.ResizeMode.NoResize; ID = Guid.NewGuid(); AddedAt = DateTime.Now; AddToList(); ToolTip = ID.ToString(); #region Event to Rx Observable WindowLocationChangedRxEventArgs = from evt in Observable.FromEventPattern<EventHandler, EventArgs>(h => this.LocationChanged += h, h => this.LocationChanged -= h) select evt; WindowLocationChangedRxEventArgs.Subscribe(evt => { Window2 w = evt.Sender as Window2; if (w.IsFullSize && !w.SwitchInProgress) { LocationOfArrangement = new Point(w.Left, w.Top); w.ArrangeDisplay(); } if (w.SwitchInProgress) w.SwitchInProgress = false; }); WindowMouseDownRxEventArgs = from evt in Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => MouseDown += h, h => MouseDown -= h) select evt; WindowMouseDownRxEventArgs.Subscribe(evt => { Window2 w = evt.Sender as Window2; if (w.IsFullSize) return; SwitchInProgress = true; ArrangeDisplay(true); }); HeaderPreviewMouseMoveRxEventArgs = from evt in Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => header.PreviewMouseMove += h, h => header.PreviewMouseMove -= h) select evt; HeaderPreviewMouseMoveRxEventArgs.Subscribe(evt => { if (evt.EventArgs.LeftButton == MouseButtonState.Pressed) { DragMove(); } }); #endregion t1.Text = "Just for Identication: " + ID + " " + AddedAt.ToString(); t2.Text = "Managed Thread Id " + System.Threading.Thread.CurrentThread.ManagedThreadId; } static Window2() { TopWindowList = new SortedList<DateTime, Window2>(); LocationOfArrangement = new Point(300, 300); } #endregion #region List public void RemoveFromListById(Guid id) { var w= TopWindowList.FirstOrDefault(_=>_.Value.ID==id); TopWindowList.Remove(w.Key); } public void AddToList() { Window2 w = (from _ in TopWindowList.Values where _.ID == this.ID select _).FirstOrDefault(); if (w == null) { TopWindowList.Add(AddedAt, this); } } #endregion #region Arrange public void ArrangeDisplay(bool MakeMeFullSize = false) { ArrangeSize(MakeMeFullSize); ArrangeLocaton(); ToggleContent(); } #endregion #region Content public void ShowFullContent() { v.Visibility = System.Windows.Visibility.Collapsed; g.Visibility = System.Windows.Visibility.Visible; } public void ShowSmallContent() { v.Visibility = Visibility.Visible; g.Visibility = System.Windows.Visibility.Collapsed; } private void ToggleContent() { foreach (var t in TopWindowList.Values) { if (t.IsFullSize) t.ShowFullContent(); else t.ShowSmallContent(); } } #endregion #region Location private void ArrangeLocaton() { Window2 prevThumbnail = null; TopWindowList.OrderBy(_ => _.Key); for (int i = 0; i < TopWindowList.Values.Count;i++ ) { var t = TopWindowList.Values[i]; if (t.IsFullSize) { t.Top = LocationOfArrangement.Y; t.Left = LocationOfArrangement.X; } else { if (prevThumbnail == null) { t.Top = LocationOfArrangement.Y; t.Left = LocationOfArrangement.X - t.Width - 2; } else { double d1 = 0; double d2 = 0; d1 = prevThumbnail.Top + prevThumbnail.Height; d2 = prevThumbnail.Left; t.Top = d1 + 2; t.Left = d2; } prevThumbnail = t; } } } #endregion #region Sizing private bool IsFullSize { get; set; } private void ShowFullSize() { ResizeMode = System.Windows. ResizeMode.CanResize; Width = 300; Height = 300; ResizeMode = System.Windows.ResizeMode.NoResize; IsFullSize = true; } private void ShowThumbnailSize() { ResizeMode = System.Windows.ResizeMode.CanResize; Width = 50; Height = 50; ResizeMode = System.Windows.ResizeMode.NoResize; IsFullSize = false; } private void ArrangeSize(bool MakeMeFullSize = false) { if (MakeMeFullSize) foreach (var t in TopWindowList.Values) { if (t.ID == this.ID) t.ShowFullSize(); else t.ShowThumbnailSize(); } else { var q = (from _ in TopWindowList.Values where _.IsFullSize select _).FirstOrDefault(); if (q == null && TopWindowList.Values.Count > 0) { TopWindowList.OrderBy(_ => _.Key); TopWindowList.Values[0].ArrangeDisplay(true); } if(q!=null) { if (q.ID != ID) { ShowThumbnailSize(); } } } } #endregion } }

Xaml code

<Window x:Class="WpfApplication1.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window2" Height="300" Width="300" BorderBrush="Gray" BorderThickness="1" ShowInTaskbar="False"> <Grid> <Grid Name="g"> <Grid.RowDefinitions> <RowDefinition Height="21*"/> <RowDefinition Height="111*"/> <RowDefinition Height="95*"/> <RowDefinition Height="40*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" MinWidth="144"/> <ColumnDefinition Width="150" MinWidth="148"/> </Grid.ColumnDefinitions> <Rectangle Name="header" Fill="Gray" Grid.Row="0" HorizontalAlignment="Left" Height="20" Stroke="Black" VerticalAlignment="Top" Width="292" Grid.Column="0" Grid.ColumnSpan="2" /> <TextBox Name="t1" Height="101" Margin="10,0,18,0" Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" Text="TextBox" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="2"/> <TextBox Name="t2" Height="89" Margin="10,4,18,0" Grid.Row="2" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="2"/> <Button Content="Send" Grid.Row="3" Grid.Column="1" Margin="10,4,17,6"/> <Button Content="Close" Grid.Row="3" Grid.Column="0" Margin="10,4,10,6"/> </Grid> <Viewbox Name="v" Visibility="Collapsed" > <StackPanel> <TextBlock TextWrapping="Wrap" >Thumbnail Content </TextBlock> <TextBlock TextWrapping="Wrap" >Small Size Shrinkable</TextBlock> </StackPanel> </Viewbox> </Grid> </Window>

Code To Simulate Windows Mutiple PopUp

private void Button_Click(object sender, RoutedEventArgs e) { Observable.Interval(TimeSpan.FromSeconds(3)).Subscribe((t) => { Dispatcher.Invoke(() => { Window2 w = new Window2() { }; w.Show(); w.ArrangeDisplay(); }); }); }

Saturday, September 14, 2013

Directly Accessing Dispatcher from Observables may freeze UI

The following code made UI not responsive, can not move either main or popup windows.
It seems that directly hitting dispatcher can overwhelm it. Consider using BlockingCollection.



// Observer Popup window every 5 seconds. e.g. RFQ and its updates come in during peak market hours.

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Observable.Interval(TimeSpan.FromSeconds(5)).Subscribe((t)=>
            {
                this.Dispatcher.Invoke(() => { (new Window1() { Title = t.ToString() }).Show(); });
               // this.Dispatcher.BeginInvoke(new Action(() => { (new Window1() { Title = t.ToString() }).Show(); }));  // same behavior

        });



// each window may take long time to PopUp during data delay or binding on UI Thread.
   public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Thread.Sleep(5000); // simulating delay on UI Thread.
        }
    }

One solution is to use multiple dispatchers

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            Observable.Interval(TimeSpan.FromSeconds(5)).Subscribe((t) =>
            {
                Thread th = new Thread(new ThreadStart(show));
                th.SetApartmentState(ApartmentState.STA);
                th.IsBackground = true;
                th.Start();

            });
        }
        void show()
        {

            Windows w= new Window1() { Title = DateTime.Now.ToString() });
w.Show();
  w.Closed += (sender2, e2) =>
      w.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run(); }

Saturday, September 7, 2013

Converting stream to Observable through Async Pattern


        static void Main(string[] args)
        {
            IPEndPoint p = new IPEndPoint(IPAddress.Parse("192.168.0.107"), 11000
            Socket sok = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            
            sok.Connect(p);
            NetworkStream s= new NetworkStream(sok);
            var f = Observable.FromAsyncPattern(s.BeginRead, s.EndRead);
            byte[] b = new byte[60];

           var obs2 = Observable.While(() => s.DataAvailable, Observable.Defer(() => f(b, 0, 60)));
           Thread.Sleep(5000);
           obs2.Subscribe(x =>
                        {
                            Thread.Sleep(1000);
                            char[] cs = Encoding.UTF7.GetChars(b, 0, x);
                            Console.WriteLine("out" + new string(cs));
                        });
      
           Console.ReadLine();        
        }
Note that FromAsyncPattern is marked obsolete.

Socket Server stream out data:

        static void Main(string[] args)
        {
            byte[] bytes = new Byte[1024];

            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(10);

                // Start listening for connections.
                
           
                    Console.WriteLine("Waiting for a connection...");
                    Socket handler = listener.Accept();
                    while (true)
                    {
                        Thread.Sleep(1000);
                        string s = "Data @ " + DateTime.Now.ToString();
                            Console.WriteLine("sending..." +s);
                        byte[] msg = Encoding.ASCII.GetBytes(s);

                        handler.Send(msg);
                    }
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                  
                    Console.ReadLine();
               
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();

        }
    }

Monday, September 2, 2013

Subscriber block Observable

Rx observable waits for each subscribe to process in single threaded fashion. So Blocking happens

            var obs = System.Reactive.Linq.Observable.Range(0, 200, System.Reactive.Concurrency.Scheduler.TaskPool).Publish();
            obs.Timestamp().Select(i => i).
            Subscribe(i => { Console.WriteLine("sub1 block " + i); Thread.Sleep(3000); });

            obs.Timestamp().Select(i => i).
Subscribe(i => { Console.WriteLine("sub2  " + i); });
            obs.Connect();

            Console.ReadLine();  

Saturday, June 15, 2013

Calculating Max number of Pages used to host Handle Table Enties by Executive


Here are information related to System Internal in general
http://live.sysinternals.com/

http://technet.microsoft.com/en-us/sysinternals/bb963901.aspx

http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx

The JPG shows the actual calculation:


Thursday, June 13, 2013

Set up Monitoring Desktop Heap as Performance Alert

Find Heap Size at registion location LM\System\CurrentControlSet\Control\SessionManager\SubSystem\Windows\

%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,3072,512 ....

1024k = Common Size, Do not change
3072k = Interactive Size/Desktop, Do not change
512k = Non-Intereactive Size, can change but very careful

Buffer size is 48M and everything must fit into it.

So each DeskTop Heap can support (49152-3072)/512 =(48M-3M)/512K=95 processes.

Set up Alert:
Control Panel-> Admin->Perf->Perf Log and Alert->New Alert Settings->Add Counter
->System Perf Object->Processes Counter->Add->DropDown="Alert when Value over" 95,
->Action Tab->Check "Log an entry in Event Log"->Ok, Start Alert.

Monday, May 27, 2013

Subjects in Science worthy of life time commitment

(1) Build a bio Transistor.
(2) Quantum bit based computer to simulate Bio System evolution and behavior

C# code to stress Memory (Copy from MSDN)

this code is very usefull to bump up resource usage and run your code for exposing bugs
class Test
{
   static void Main() {
      unsafe {
         byte* buffer = (byte*)Memory.Alloc(256);
         try {
            for (int i = 0; i < 256; i++) buffer[i] = (byte)i;
            byte[] array = new byte[256];
            fixed (byte* p = array) Memory.Copy(buffer, p, 256);
         }
         finally {
            Memory.Free(buffer);
         }
         for (int i = 0; i < 256; i++) Console.WriteLine(array[i]);
      }
   }
}
 
 
 
using System;
using System.Runtime.InteropServices;
public unsafe class Memory
{
   // Handle for the process heap. This handle is used in all calls to the
   // HeapXXX APIs in the methods below.
   static int ph = GetProcessHeap();
   // Private instance constructor to prevent instantiation.
   private Memory() {}
   // Allocates a memory block of the given size. The allocated memory is
   // automatically initialized to zero.
   public static void* Alloc(int size) {
      void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);
      if (result == null) throw new OutOfMemoryException();
      return result;
   }
   // Copies count bytes from src to dst. The source and destination
   // blocks are permitted to overlap.
   public static void Copy(void* src, void* dst, int count) {
      byte* ps = (byte*)src;
      byte* pd = (byte*)dst;
      if (ps > pd) {
         for (; count != 0; count--) *pd++ = *ps++;
      }
      else if (ps < pd) {
         for (ps += count, pd += count; count != 0; count--) *--pd = *--ps;
      }
   }
   // Frees a memory block.
   public static void Free(void* block) {
      if (!HeapFree(ph, 0, block)) throw new InvalidOperationException();
   }
   // Re-allocates a memory block. If the reallocation request is for a
   // larger size, the additional region of memory is automatically
   // initialized to zero.
   public static void* ReAlloc(void* block, int size) {
      void* result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, block, size);
      if (result == null) throw new OutOfMemoryException();
      return result;
   }
   // Returns the size of a memory block.
   public static int SizeOf(void* block) {
      int result = HeapSize(ph, 0, block);
      if (result == -1) throw new InvalidOperationException();
      return result;
   }
   // Heap API flags
   const int HEAP_ZERO_MEMORY = 0x00000008;
   // Heap API functions
   [DllImport("kernel32")]
   static extern int GetProcessHeap();
   [DllImport("kernel32")]
   static extern void* HeapAlloc(int hHeap, int flags, int size);
   [DllImport("kernel32")]
   static extern bool HeapFree(int hHeap, int flags, void* block);
   [DllImport("kernel32")]
   static extern void* HeapReAlloc(int hHeap, int flags,
      void* block, int size);
   [DllImport("kernel32")]
   static extern int HeapSize(int hHeap, int flags, void* block);
}

Wednesday, April 10, 2013

Detect WPF Window out of bound for multiple monitor

            Point p =new Point(left, top);
            bool outOfBoundHorizontal = p.X < SystemParameters.VirtualScreenLeft || p.X > SystemParameters.VirtualScreenLeft + SystemParameters.VirtualScreenWidth;
            bool outOfBoundVertical = p.Y < SystemParameters.VirtualScreenTop || p.Y > SystemParameters.VirtualScreenTop + SystemParameters.VirtualScreenHeight;

Note that VirtualScreenHeight/Width considered Multiple Monitor with various Display Positioning, It can start at negative  and to position 1/3, use 1/0/3.0*(SystemParameters.VirtualScreenLeft + SystemParameters.VirtualScreenWidth), not just width.

TO reposition find Primary Monitor
           if (outOfBoundHorizontal || outOfBoundVertical)
            {
                var primaryMonitor = Screen.AllScreens.FirstOrDefault(s => s.Primary);
                if (primaryMonitor == null)
                {
                  wnd.Left = 0;
                  wnd.Top = 0; 
                }
                else
                {
                    // Fit into Primary Monitor if possible. Note Primary Monitor start @ (0,0)
                    wnd.Left = primaryMonitor.Bounds.Left + Math.Max(primaryMonitor.Bounds.Width- wnd.Width, 0);
                    wnd.Top = primaryMonitor.Bounds.Height + Math.Max(primaryMonitor.Bounds.Height - wnd.Height, 0);                   
                }
            }

Update--- the above code does not work property due to measurement issues , flip monitor, Landscape/Portrait, L shapes.
1 point = 1/72 inch, 1 px = 1/96 inch. The size could use either px or point per Graphics.PageUnit

Rectangle hitTestRec= new System.Drawing.Rectange(left,top, new size(2,2))

var hitTestMonitor= System.Windows.Form.Screen.AllScreens.FirstOrDefault(s => s.Bounds.Contains(hitTestRect));
bool outOfBound = hitTestMonitor ==null;