Volunteer .NET Evangelist

A well oiled machine can’t run efficiently, if you grease it with water.
   :: 首页 ::  :: 联系 :: 订阅 订阅 :: 管理

2006年2月28日

    For all of you who follow up my blog closely, you will probably remember that I have written a little application in which you can edit your xaml snippet and have that sinppet executed in real time, and this is what exactly the XamlPad.exe which is shipped with the WINFX SDK does. But in that little application, I just used the plain text editor for editing Xaml, you know, no syntax highlighting, no line numbering, no auto indentation etc. Fortunately the TextEditorControl which is available from the SharpDevelop project meets exactly what I need. So I can reuse that control without reinventing the wheel. I have tried to use the TextEditorControl in my WPF version of XamlPad, but It fails, even fails with no clue. But I know this control can work pretty well in Winforms application, so instead of hosting this control in WPF, I just use this control in Winforms application, and use Crossbow to host the necessary WPF controls in this Winforms application.
    Just as before, you have to include some important assemblies into your project, they are WindowsBase.dll, PresentationCore.dll, PresentationFramework.dll, UIAutomationProvider.dll, UIAutomationTypes.dll, and WindowsFormsIntegration.dll.
    Then you can add a Winforms TabControl into containing Form through classical Drag & Drop operation, and set those properties for the TabControl instance, immediately after that you can write something like the following in code:
 private void SetupExecutionPad()
        {
            ElementHost host 
= new ElementHost();
            host.Dock 
= DockStyle.Fill;
            executionPad 
= new ContentControl();
            host.Controls.Add(executionPad);
            tabExectionView.Controls.Add(host);
        }

    This private helper method will perform the necessary operations to host WPF control. First, we need to instantiate an ElementHost control, Just as WindowsFormsHost control does in WPF, this control is something like a wrapper or container which can has a single WPF control as its child control. and then you can create any WPF control(here we create a ContentControl for displaying the dynamically compiled Xaml) and add it to the ElementHost control's ControlCollection.
    Next, we should initialize some TextEditorControl's properties to make it support XML syntax highlighting and other flashy features.
private void SetupXamlEditor()
        {
            xamlEditor.Document.HighlightingStrategy 
= HighlightingStrategyFactory.CreateHighlightingStrategy("XML");
            xamlEditor.Document.FormattingStrategy 
= new DefaultFormattingStrategy();
            DefaultTextEditorProperties properties 
= new DefaultTextEditorProperties();
            properties.Font 
= new Font("Verdana", 10f);
            properties.IndentStyle 
= IndentStyle.Smart;
            properties.ShowSpaces 
= false;
            properties.LineTerminator 
= "\r\n";
            properties.ShowTabs 
= false;
            properties.ShowInvalidLines 
= false;
            properties.ShowEOLMarker 
= false;
            properties.UseAntiAliasedFont 
= true;
            properties.EnableFolding 
= true;
            properties.TabIndent 
= 3;
            properties.AllowCaretBeyondEOL 
= false;
            properties.AutoInsertCurlyBracket 
= true;
            properties.BracketMatchingStyle 
= BracketMatchingStyle.After;
            properties.ConvertTabsToSpaces 
= false;
            properties.ShowMatchingBracket 
= true;
            xamlEditor.TextEditorProperties 
= properties;
        }

    Okay, this is what we should do to revamp the XamlPad application, the following is the screenshot of this little fancy application:

    XamlPad in ExecutionView:



    XamlPad in XamlView


    To make this application a full-blown Xaml IDE, there are hoards of things which I have to do, but I just need a simple primitive XamlPad, and this one serves me pretty well in writing Xaml snippets.
    For all of you who are interested in this little application, you can download its source code from here

posted @ 2006-02-28 23:26 Sheva 阅读(2134) 评论(3) 编辑

    Crossbow, OMG, WTF?
    Well, Crossbow is the codename for the interoperability technology between Windows Forms and Windows Presentation Foundation. Crossbow enables you to host Windows
Forms control in your WPF application, and vice versa. In this post, I will demonstrate how to use Windows Forms control in WPF application, in my next post, I will demonstrate another simple ridiculous Windows Forms application which will host Windows Presentation Foundation controls.
    So, the first step is to add some assembly reference into your WPF application project. there are two important assemblies you should include, they are WindowsFormsIntegration.dll and System.Windows.Forms.dll, after you're done with this, you can reference Windows.Forms.Integration and System.Windows.Forms namespaces in the Xaml code as follows:
<Window x:Class="CrossBowDemo.MainWindow"
    xmlns:wfi 
="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
    xmlns:wf 
="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    Title
="Hosting Windows Forms Control In WPF" 
    Height
="300" 
    Width
="650" 
    ResizeMode
="NoResize"
    Loaded
="WindowLoadedHandler" 
    
>
  
<DockPanel>
    
<wfi:WindowsFormsHost>
       
<!-- Set some properties on Windows Forms control in Xaml -->
      
<wf:DataGridView x:Name="dataGridView" Dock="Fill" SelectionMode="FullRowSelect"/>
    
</wfi:WindowsFormsHost>
  
</DockPanel>
</Window>

    Note that I declare two additional Xml namespace references in Xaml so that the Xaml parser knows how to parse the Windows Forms control tag.

xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:wf ="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

    Then you should declare the WindowsFormsHost control in the Xaml, this control acts like a sticky point between WPF and Windows Forms.
    After that, you can declare any Windows Forms control within the
WindowsFormsHost control, here we add a DataGridView control for displaying the profiles of some famous soccer players.

<wfi:WindowsFormsHost>
       
<!-- Set some properties on Windows Forms control in Xaml -->
      
<wf:DataGridView x:Name="dataGridView" Dock="Fill" SelectionMode="FullRowSelect"/>
    
</wfi:WindowsFormsHost>

    Note that you can declaratively set the properties of Windows Forms control(a.k.a DataGridView) in Xaml. and of course you can also set this control's properties in code, here we set additional DataGridView's propeties in code, and then bind the profile data with this control, all those plumbing code should be in the Window's Loaded event handler method:

private void WindowLoadedHandler(Object sender, EventArgs e)
        {
            
// Set some properties on Windows Forms control in code.
            dataGridView.AlternatingRowsDefaultCellStyle.BackColor = GdiPlus::SystemColors.InactiveCaptionText;
            dataGridView.AllowUserToAddRows 
= true;

            
// Load players information.
            DataSet ds = new DataSet();
            ds.ReadXml(
"..\\..\\players.xml");
            playerBindingSource 
= new Winforms::BindingSource(ds, "player");
            dataGridView.DataSource 
= playerBindingSource;
        }

    Note that you cannot move the above code into the Window's constructor, if you do so, an exception will be thrown.
    Okay, this is all what we should do for hosting Windows Forms control in WPF, let's see our little application in action:



    For complete source code, please check here

posted @ 2006-02-28 01:37 Sheva 阅读(2218) 评论(2) 编辑