您的位置:首页 > 其它

WPF与Prism一并学习(四)

2017-12-01 08:53 363 查看

创建WPF程序的三种方式:

1.只使用代码

2.使用代码和未经编译的标记(XAML)

3.使用代码和编译过的标记(BAML)

第一种不写了,比较简单

第二种:

所谓的第二种方法就是直接读一个XAML文件,解析它并创建界面元素,要注意的是要读的XAML文件属性要设置成如下的样子



[csharp]
view plain
copy

print?




    private Button button1;          
  
    public Window1(string xamlFile)  
    {  
        InitializeComponent(xamlFile);  
    }                  
  
    private void InitializeComponent(string xamlFile)  
    {  
        // Configure the form.  
        this.Width = this.Height = 285;  
        this.Left = this.Top = 100;  
        this.Title = "Dynamically Loaded XAML";  
  
        // Get the XAML content from an external file.  
        DependencyObject rootElement;  
        using (FileStream fs = new FileStream(xamlFile, FileMode.Open))  
        {  
            rootElement = (DependencyObject)XamlReader.Load(fs);  
        }  
  
        // Insert the markup into this window.  
        this.Content = rootElement;                         
  
        // Find the control with the appropriate name.  
        //button1 = (Button)LogicalTreeHelper.FindLogicalNode(rootElement, "button1");  
        FrameworkElement frameworkElement = (FrameworkElement)rootElement;  
        button1 = (Button)frameworkElement.FindName("button1");  
  
        // Wire up the event handler.  
        button1.Click += new RoutedEventHandler(button1_Click);  
    }  
      
    private void button1_Click(object sender, RoutedEventArgs e)  
    {  
        button1.Content = "Thank you.";  
    }  
}  



[csharp]
view plain
copy

print?

    private Button button1;          
  
    public Window1(string xamlFile)  
    {  
        InitializeComponent(xamlFile);  
    }                  
  
    private void InitializeComponent(string xamlFile)  
    {  
        // Configure the form.  
        this.Width = this.Height = 285;  
        this.Left = this.Top = 100;  
        this.Title = "Dynamically Loaded XAML";  
  
        // Get the XAML content from an external file.  
        DependencyObject rootElement;  
        using (FileStream fs = new FileStream(xamlFile, FileMode.Open))  
        {  
            rootElement = (DependencyObject)XamlReader.Load(fs);  
        }  
  
        // Insert the markup into this window.  
        this.Content = rootElement;                         
  
        // Find the control with the appropriate name.  
        //button1 = (Button)LogicalTreeHelper.FindLogicalNode(rootElement, "button1");  
        FrameworkElement frameworkElement = (FrameworkElement)rootElement;  
        button1 = (Button)frameworkElement.FindName("button1");  
  
        // Wire up the event handler.  
        button1.Click += new RoutedEventHandler(button1_Click);  
    }  
      
    private void button1_Click(object sender, RoutedEventArgs e)  
    {  
        button1.Content = "Thank you.";  
    }  
}  

private Button button1;

public Window1(string xamlFile)
{
InitializeComponent(xamlFile);
}

private void InitializeComponent(string xamlFile)
{
// Configure the form.
this.Width = this.Height = 285;
this.Left = this.Top = 100;
this.Title = "Dynamically Loaded XAML";

// Get the XAML content from an external file.
DependencyObject rootElement;
using (FileStream fs = new FileStream(xamlFile, FileMode.Open))
{
rootElement = (DependencyObject)XamlReader.Load(fs);
}

// Insert the markup into this window.
this.Content = rootElement;

// Find the control with the appropriate name.
//button1 = (Button)LogicalTreeHelper.FindLogicalNode(rootElement, "button1");
FrameworkElement frameworkElement = (FrameworkElement)rootElement;
button1 = (Button)frameworkElement.FindName("button1");

// Wire up the event handler.
button1.Click += new RoutedEventHandler(button1_Click);
}

private void button1_Click(object sender, RoutedEventArgs e)
{
button1.Content = "Thank you.";
}
}
上面直接把Window1.xaml从硬盘读到文件流中,再转化成DependencyObject对象,DependencyObject是所有WPF控件继承的基类.

上面被注释的代码

[csharp]
view plain
copy

print?




button1 = (Button)LogicalTreeHelper.FindLogicalNode(rootElement, "button1");  



[csharp]
view plain
copy

print?

button1 = (Button)LogicalTreeHelper.FindLogicalNode(rootElement, "button1");  

button1 = (Button)LogicalTreeHelper.FindLogicalNode(rootElement, "button1");


[csharp]
view plain
copy

print?




FrameworkElement frameworkElement = (FrameworkElement)rootElement;  
            button1 = (Button)frameworkElement.FindName("button1");  



[csharp]
view plain
copy

print?

FrameworkElement frameworkElement = (FrameworkElement)rootElement;  
            button1 = (Button)frameworkElement.FindName("button1");  

FrameworkElement frameworkElement = (FrameworkElement)rootElement;
button1 = (Button)frameworkElement.FindName("button1");
是等效的,LogicalTreeHelper是一个辅助类,具有查找一棵完整控件对象树的能力,这个示例中XAML文件中的根元素是DockPanel,DockPanel又继承自FrameworkElement类,所以使用FrameworkElement.FindName()方法同样可以找到控件对象.

第三种:

这种方法是VS自己支持的,所有代码都是自动生成的,不用我们人为去编码,即把XAML编译成BAML文件,再嵌入dll中作为资源保存,程序运行时再从dll中读出来. 读BMAL比直接读XMAL文件效率要高,因为BMAL已经经过了优化,文件体积也比XMAL小. 编译器在编译成会生成一个BMAL文件,和一个分部类,它们会放在项文件夹的obj\Debug子文件夹中.

下面来看看这个VS自动生成的部分类,Window1.g.cs (只呈现主要逻辑代码,省略掉非关键部分)

[csharp]
view plain
copy

print?




/// <summary>  
/// Window1  
/// </summary>  
public partial class Window1 : System.Windows.Window, System.Windows.Markup.IComponentConnector {  
      
     
    internal System.Windows.Controls.TextBox txtQuestion;  
      
    internal System.Windows.Controls.Button cmdAnswer;  
      
    internal System.Windows.Controls.TextBox txtAnswer;  
     
    #line default  
    #line hidden  
      
    private bool _contentLoaded;  
      
    /// <summary>  
    /// InitializeComponent  
    /// </summary>  
    public void InitializeComponent() {  
        if (_contentLoaded) {  
            return;  
        }  
        _contentLoaded = true;  
        System.Uri resourceLocater = new System.Uri("window1.baml", System.UriKind.Relative);  
          
        System.Windows.Application.LoadComponent(this, resourceLocater);  
         
        #line default  
        #line hidden  
    }  
      
   ......  
    void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {  
        switch (connectionId)  
        {  
        case 1:  
        this.txtQuestion = ((System.Windows.Controls.TextBox)(target));  
        return;  
        case 2:  
        this.cmdAnswer = ((System.Windows.Controls.Button)(target));  
          
        this.cmdAnswer.Click += new System.Windows.RoutedEventHandler(this.cmdAnswer_Click);  
          
  
        return;  
        case 3:  
        this.txtAnswer = ((System.Windows.Controls.TextBox)(target));  
        return;  
        }  
        this._contentLoaded = true;  
    }  
}  



[csharp]
view plain
copy

print?

/// <summary>  
/// Window1  
/// </summary>  
public partial class Window1 : System.Windows.Window, System.Windows.Markup.IComponentConnector {  
      
     
    internal System.Windows.Controls.TextBox txtQuestion;  
      
    internal System.Windows.Controls.Button cmdAnswer;  
      
    internal System.Windows.Controls.TextBox txtAnswer;  
     
    #line default  
    #line hidden  
      
    private bool _contentLoaded;  
      
    /// <summary>  
    /// InitializeComponent  
    /// </summary>  
    public void InitializeComponent() {  
        if (_contentLoaded) {  
            return;  
        }  
        _contentLoaded = true;  
        System.Uri resourceLocater = new System.Uri("window1.baml", System.UriKind.Relative);  
          
        System.Windows.Application.LoadComponent(this, resourceLocater);  
         
        #line default  
        #line hidden  
    }  
      
   ......  
    void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {  
        switch (connectionId)  
        {  
        case 1:  
        this.txtQuestion = ((System.Windows.Controls.TextBox)(target));  
        return;  
        case 2:  
        this.cmdAnswer = ((System.Windows.Controls.Button)(target));  
          
        this.cmdAnswer.Click += new System.Windows.RoutedEventHandler(this.cmdAnswer_Click);  
          
  
        return;  
        case 3:  
        this.txtAnswer = ((System.Windows.Controls.TextBox)(target));  
        return;  
        }  
        this._contentLoaded = true;  
    }  
}  

/// <summary>
/// Window1
/// </summary>
public partial class Window1 : System.Windows.Window, System.Windows.Markup.IComponentConnector {

internal System.Windows.Controls.TextBox txtQuestion;

internal System.Windows.Controls.Button cmdAnswer;

internal System.Windows.Controls.TextBox txtAnswer;

#line default
#line hidden

private bool _contentLoaded;

/// <summary>
/// InitializeComponent
/// </summary>
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Uri resourceLocater = new System.Uri("window1.baml", System.UriKind.Relative);

System.Windows.Application.LoadComponent(this, resourceLocater);

#line default
#line hidden
}

......
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 1:
this.txtQuestion = ((System.Windows.Controls.TextBox)(target));
return;
case 2:
this.cmdAnswer = ((System.Windows.Controls.Button)(target));

this.cmdAnswer.Click += new System.Windows.RoutedEventHandler(this.cmdAnswer_Click);

return;
case 3:
this.txtAnswer = ((System.Windows.Controls.TextBox)(target));
return;
}
this._contentLoaded = true;
}
}


方法二中的XamlReader用处很大,下面的代码摘自这个地方

通过XamlReader 动态构建并实例化一个Window
<span style="color: green;">//XamlReader
</span><span style="color: rgb(43, 145, 175);">StringBuilder </span>strXMAL = <span style="color: blue;">new </span><span style="color: rgb(43, 145, 175);">StringBuilder</span>(<span style="color: rgb(163, 21, 21);">"<Window "</span>);
strXMAL.Append(<span style="color: rgb(163, 21, 21);">"xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" "</span>);
strXMAL.Append(<span style="color: rgb(163, 21, 21);">"xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" "</span>);
strXMAL.Append(<span style="color: rgb(163, 21, 21);">"Title=\"Window2\" Height=\"600\" Width=\"600\">"</span>);
strXMAL.Append(<span style="color: rgb(163, 21, 21);">"</Window>"</span>);
<span style="color: blue;">var </span>window = (<span style="color: rgb(43, 145, 175);">Window</span>)<span style="color: rgb(43, 145, 175);">XamlReader</span>.Parse(strXMAL.ToString());
window.ShowDialog();

作者还自己实现了BMAL文件的Reader和Writer,有兴趣可以研究研究,一般情况下也用不上的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: