כאשר LINQ פוגש את WPF

23 ביולי 2007

אין תגובות

במרכז הבין תחומי הכרתי לראשונה את SCHEME והתאהבתי. בפוסט זה אני מנסה להמחיש את התיכנות הפונקציונאלי ע"י תמונות. החומר מבוסס על העיונות מהספר Structure and Interpretation of Computer Programs.

המטרה ליצור תמונות בפונקציות רקורסויות, לדוגמא:

image image

פתרון:

1. נגדיר את הפונקציות הבסיס:

  • Below
    image 
    public static UIElement Below( this UIElement source )
    {
                UIElement cloned = source.Clone();
                return Below( source, cloned );
    }
    public static UIElement Below( this UIElement source, UIElement element )
    {
                Grid g = new Grid();
                RowDefinition r1 = new RowDefinition ();
                r1.Height = new GridLength ( 0.5 , GridUnitType.Star );
                RowDefinition r2 = new RowDefinition();
                r2.Height = new GridLength ( 0.5 , GridUnitType.Star );
                g.RowDefinitions.Add( r1 );
                g.RowDefinitions.Add( r2 );
                g.ShowGridLines = ShowGridLines;
                g.Children.Add( source );
                g.Children.Add( element );
                Grid.SetRow( source, 0 );
                Grid.SetRow( element, 1 );
    
                return g;
     }

  • Beside
    image
    public static UIElement Below( this UIElement source )
    {
                UIElement cloned = source.Clone();
                return Below( source, cloned );
    }
    public static UIElement Below( this UIElement source, UIElement element )
    {
                Grid g = new Grid();
                RowDefinition r1 = new RowDefinition ();
                r1.Height = new GridLength ( 0.5 , GridUnitType.Star );
                RowDefinition r2 = new RowDefinition();
                r2.Height = new GridLength ( 0.5 , GridUnitType.Star );
                g.RowDefinitions.Add( r1 );
                g.RowDefinitions.Add( r2 );
                g.ShowGridLines = ShowGridLines;
                g.Children.Add( source );
                g.Children.Add( element );
                Grid.SetRow( source, 0 );
                Grid.SetRow( element, 1 );
    
                return g;
    }

    מה קיבלנו?

    UIElementimage
         .Beside()
         .Below()
     שימו לב שיש ליצור CLONE כדי שנוכל לעבוד עם אותו UIElement במספר מקומות שונים בעץ.
    לשם כך יש לכתוב את הפונקציה CLONE הבאה:

  • private static UIElement Clone( this UIElement source )
     {
                string clon = XamlWriter.Save( source );
                UIElement cloned = (UIElement)XamlReader.Load(
                    XmlReader.Create( new StringReader( clon ) ) );
                return cloned;
    }

  • right-split n
     The image “http://mitpress.mit.edu/sicp/full-text/book/ch2-Z-G-36.gif” cannot be displayed, because it contains errors.


    public static UIElement RightSplit( this UIElement source, int n )
    {
                if( n == 0  || n < 0 )
                    return source.Clone();
    
                UIElement smaller = RightSplit( source, --n );
    
                return Beside( source.Clone() , smaller.Below() );
     }image
    // Use It
    UIElement
    .RightSplit(4);

 
  • corner-split n

      

public static UIElement CornerSplit( this UIElement source, int n )
 {
            if( n == 0 || n < 0 )
                return source.Clone();

            int s = n - 1;

            UIElement up          = UpSplit( source, s );
            UIElement right       = RightSplit( source, s );
            
            UIElement topLeft     = up.Beside();
            UIElement bottomRight = right.Below();
            
            UIElement corner      = CornerSplit( source, s );
            
            return
                Beside( Below( source.Clone(), topLeft ),
                        Below( bottomRight, corner ) );
}
image 
// Use It
UIElement
.CornerSplit( 4 );
 


 
  • Flipped Pairs
    למקצעונים בלבד !!!
// func that create func base on 4 funcs.
public
static Func< UIElement , UIElement > SquareOfFour( Func<UIElement,UIElement> tl, Func<UIElement,UIElement> tr, Func<UIElement,UIElement> bl, Func<UIElement,UIElement> br ) { return delegate( UIElement p ) { UIElement top = Beside( tl( p ), tr( p ) ); UIElement bottom = Beside( bl( p ), br( p ) ); return Below( top, bottom ); }; } public static UIElement FlippedPairs( this UIElement source ) { var func = SquareOfFour(
tr => tr.FlipV().FlipH() , tl => tl.FlipV(), FlipH, bl => bl.Clone() ); return func( source ); }
image 
// Use It
UIElement
   .CornerSplit( 4 )
   .FlippedPairs();

  • Spine
      
    public static UIElement Spine( this UIElement source, int n, int angle )
    {
       return source.Spine( new Grid(), n, angle, 0.5, 0.5 );
    }
    public static UIElement Spine( this UIElement source, 
    int n, int angle, double x, double y ) { return source.Spine( new Grid(), n, angle, x, y ); } public static UIElement Spine( this UIElement source, Panel panel,
    int n, int angle, double x, double y ) { if( n > 0 ) source.Spine( panel, --n, angle ,x , y ); if( n == 0 ) { panel.Children.Add( source.Clone() ); return panel; } panel.Children.Add( source.Rotate( angle * n , x , y) ); return panel; }
    public static UIElement Rotate( this UIElement source,
    int angle, double x , double y ) { UIElement e = source.Clone(); e.RenderTransformOrigin = new Point( x, y ); TransformGroup tg; if( e.RenderTransform is TransformGroup ) { tg = e.RenderTransform as TransformGroup; } else { tg = new TransformGroup(); } tg.Children.Add( new RotateTransform( angle ) ); e.RenderTransform = tg; return e; }

    image

    // Use It

    UIElement
    .Spine( 36 , 10 , 0.5 , 0.5 );

אפשר להוסיף פונקציות כיד הדמיון…Flip, Scale  ועוד.
השלב הבא לבנות לפונקציות ביטוי ב- XAML לדוגמא:

<PictureAPI:CornerSplit Count="4">
     <PictureAPI:FlippedPairs>
        <!-- UIElement -->
        <Image/> 
    </PictureAPI:FlippedPairs>
</PictureAPI:CornerSplit>
imageimage  
 

 אותו קוד רק תמונה אחרת.
בנית קוד XAML תפורסם בפוסט המשך.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *