zoukankan      html  css  js  c++  java
  • XamlPad小程序


       
            闲着没事,仿照SDK的样子自己做了一个。

        程序主要使用了System.Windows.Markup命名空间下的XamlReader类和XamlWriter,
    其中XamlReader可以将Xaml代码转换为元素示例,而XamlWriter类可以将元素示例保存成“流”的形式。(我在之前的文章中介绍过这两个类)
     
          首先仿照SDK中的xamlPad构建出相应的界面,页面主要包括以下几个控件。一个Label控件,用于呈现XAML代码所显示的界面;一个TextBox控件,用于输入xaml代码;还有一个GridSpliter,用于调节2这的布局比例;TextBox下面紧接着一个TextBlock控件,用于显示错误信息。整体代码如下:  
    <Grid>
          <Grid.RowDefinitions>
            <RowDefinition Height="4*"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
          </Grid.RowDefinitions>
          <Label HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0"/>
          <GridSplitter Height="2" Grid.Row="1"  HorizontalAlignment="Stretch" ></GridSplitter>
          <GroupBox Grid.Row="2">
            <DockPanel>
              <Label DockPanel.Dock="Bottom"  VerticalAlignment="Bottom"  VerticalContentAlignment="Bottom" Height="30"></Label>
              <TextBox Name="xamlTB" Foreground="Red"  AcceptsReturn="True" VerticalScrollBarVisibility="Visible" ></TextBox>
            </DockPanel>
          </GroupBox>
        </Grid>

        下面看一下具体的逻辑代码:
          string xaml = value.ToString().Trim();
          XmlReader reader = new XmlTextReader(new StringReader(xaml));
          object obj = System.Windows.Markup.XamlReader.Load(reader);

          XamlReader.Load方法需要一个流对象,因为XAML是基于XML的,所以很自然的选用了XmlReader对象。这样就通过Load方法得到了一个WPF的元素,将它存储在obj变量中。得到元素后并不能直接将它赋值给Label对象,因为可能会发生错误:
          我们可能得到多种类型的元素,如过元素类型是Window,对于Window对象来说,它只能是根级元素,不能让它作为其他元素的子元素;如果是Page对象,它只能成为Window元素或者Frame的子元素;其他元素就好说了,可以直接将他们赋值给Label的Content属性:

           if ((obj as Window) != null)
                    {
                        #region
                        if (win != null)
                        {

                            win.Close();
                            win = null;
                        }
                        win = obj as Window;
                        win.Show();
                        #endregion
                    }
                    else if ((obj as Page) != null)
                    {
                        #region
                        StreamWriter sw = new StreamWriter(path);
                        XamlWriter.Save(obj, sw);
                        sw.Close();
                        Frame f = new Frame();
                        f.Source = new Uri(path, UriKind.RelativeOrAbsolute);
                        #endregion
                    }
                    else
                    {
                         ///.........
                    }
        

         整个的程序结构大概就是这样了,还是比较简单的。不过在程序的制作过程中,有一个问题困扰了我很久。究竟是应该的使用原始的.Net事件呢?还是应该使用WPF的绑定呢?实际上我在做项目的时候也遇到了这个问题。那是因为对时间要求很紧,我还是选择了前者(因为更加熟悉: P)。但这个程序我全部使用了WPF的特性,现在就给大家介绍一下:

         文本框输入,结果输出到Label中,这可以说是WPF非常典型的绑定“案例”了。不过将XAML直接输出到Label上是没有意义的,需要进行XAML-Element的转化,所以使用了IValueConverter接口。我创建了一个XamlToElement类。该类实现了IValueConverter接口IConvert和ConverterBack方法,并且在Converter中实现了对xaml到元素的转换操作。同时为了让错误信息的及时的显示到TextBlock上,XamlToElement实现了INotifyPropertyChanged接口,用于及时消息通知。完整的代码如下:

    XAML:

    <Window x:Class="XamlPad.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:XamlPad"
        Title="XamlPad" Width="746" Height="540"
        >
      <Window.Resources>
        <local:XamlToElement x:Key="xamlToElement"/>
      </Window.Resources>
        <Grid>
          <Grid.RowDefinitions>
            <RowDefinition Height="4*"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
          </Grid.RowDefinitions>
          <Label HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0"
                 Content="{Binding Path=Text,
                  ElementName=xamlTB,
                  Converter={StaticResource xamlToElement}}"/>
          <GridSplitter Height="2" Grid.Row="1"  HorizontalAlignment="Stretch" ></GridSplitter>
          <GroupBox Grid.Row="2">
            <DockPanel>
              <Label DockPanel.Dock="Bottom"  VerticalAlignment="Bottom"  VerticalContentAlignment="Bottom" Height="30"
                     Content="{Binding Path=ErrorMessage,Source={StaticResource xamlToElement}}" ></Label>
              <TextBox Name="xamlTB" Foreground="Red"  AcceptsReturn="True" VerticalScrollBarVisibility="Visible" ></TextBox>
            </DockPanel>
          </GroupBox>
        </Grid>
    </Window>


    C#:
     public class XamlToElement : IValueConverter,INotifyPropertyChanged
        {
            /// <summary>
            /// xaml转换后得到的Window对象
            /// </summary>
            Window win;
            /// <summary>
            /// xaml转换后得到的元素,其中包括Page
            /// </summary>
            object obj;
            /// <summary>
            /// 判断元素类型,Window=true,Page=false,element=null;
            /// </summary>
            bool? flag;
            /// <summary>
            /// Page的存储路径
            /// </summary>
            string path = Environment.CurrentDirectory + "\\temp.xaml";
            private string errorMessage;

            public string ErrorMessage
            {
                get { return errorMessage; }
                set
                {
                    errorMessage = value;
                    OnPropertyChanged("ErrorMessage");
                }
            }
       
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                string xaml = value.ToString().Trim();
                XmlReader reader = new XmlTextReader(new StringReader(xaml));
                try
                {
                    //得到元素对象
                    obj = System.Windows.Markup.XamlReader.Load(reader);
                    ErrorMessage = "";
                    if ((obj as Window) != null)
                    {
                        #region
                        flag = true;
                        if (win != null)
                        {

                            win.Close();
                            win = null;
                        }
                        win = obj as Window;
                        win.Show();//这里会出现闪屏的情况,大家忍耐以下吧,^_^

                        return null;
                        #endregion
                    }
                    else if ((obj as Page) != null)
                    {
                        #region
                        flag = false;
                        StreamWriter sw = new StreamWriter(path);
                        XamlWriter.Save(obj, sw);
                        sw.Close();
                        Frame f = new Frame();
                        f.Source = new Uri(path, UriKind.RelativeOrAbsolute);
                        return f;
                        #endregion
                    }
                    else
                    {
                        flag = null;
                        return obj;
                    }
                }
                catch (System.Exception a)
                {
                    ErrorMessage = a.Message;
                    if (flag == true)
                        return "";
                    else if (flag == false)
                    {
                        Frame f = new Frame();
                        f.Source = new Uri(path, UriKind.RelativeOrAbsolute);
                        return f;
                    }
                    else
                        return obj;
                }
            }
         
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return null;
            }

            public event PropertyChangedEventHandler PropertyChanged;
            // OnPropertyChanged to update property value in binding
            private void OnPropertyChanged(string propName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propName));
                }
            }
        }

       整个程序就介绍完了,希望大家多提意见:P
    源代码下载


  • 相关阅读:
    YUM软件管理
    RPM软件包管理
    Linux系统启动详解
    Linux命令行文本处理工具
    Linux多命令协作:管道及重定向
    Linux网络基础配置
    网络基础
    Linux扩展权限
    Linux权限机制
    Linux用户基础
  • 原文地址:https://www.cnblogs.com/stswordman/p/810612.html
Copyright © 2011-2022 走看看