zoukankan      html  css  js  c++  java
  • 算法之递归(4) 应用

    最近带着几个在做一个项目,UI层面用的是WPF。之前很少深入的接触WPF,不过接触后,发现WPF的却是很强大。

    至少在界面设计上的用户体验较WinForm有了大幅提升。

    项目中需要通用化几个样式,并将样式赋值给相应的控件。控件是根据配置文件动态生成的,配置文件是xml格式的层次化较多的结构。所以在动态生成的过程中采用了递归的方式来实现。

    下面是一个模拟实例。

    目标:

    将程序集“PresentationFramework"的所有类型添加到TreeView里面,如果一个类型存在基类行,那么先加入基类型,以此类推。

    实践:

    1. 创建一个WPF应用程序,添加一个xml文件,放在工程的根目录下即可。(不用放在outputdir下面)。

    2. 在此xml文件里,添加如下代码并保存。

    <Style
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:System.Windows.Controls;assembly:PresentationFramework"
        TargetType="{x:Type TypeName=TreeViewItem}">
      <Setter Property="Foreground" Value="Yellow" />
      <Setter Property="FontFamily" Value="Comic Sans MS" />
      <Setter Property="FontSize" Value="18" />
      <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
          <Setter Property="Background" Value="DarkBlue" />
        </Trigger>
      </Style.Triggers>
    </Style>

    3. 在MainWindow的cs文件中创建一个style解析器。代码如下。

            private void StyleParser()
            {
                using (FileStream fileStream = new FileStream(this.stylePath, FileMode.Open, FileAccess.Read))
                {
                    this.myStyle = (Style)XamlReader.Load(fileStream);
                }
            }

    4. 将”PresentationFramework"所有的类型以递归的形式添加到TreeView里面。

        (1) 定义递归算法。

            private void AppendItem(ItemsControl ctrl, Type type)
            {
                if (type.BaseType == null)
                    return;
    
                TreeViewItem myTreeViewItem = new TreeViewItem(){ Header = type.FullName, Style = this.myStyle};
                ctrl.Items.Add(myTreeViewItem);
                AppendItem(myTreeViewItem, type.BaseType);
            }

        (2) 初始化TreeView,并调用AppendItem方法。

            private void Window_Loaded_1(object sender, RoutedEventArgs e)
            {
                ReLayout();
    
                myTreeView.Background = Brushes.SeaGreen;
                myTreeView.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                myTreeView.VerticalAlignment = System.Windows.VerticalAlignment.Top;
    
                myTreeView.Margin = new Thickness(5, 5, 0, 0);
                this.mainGrid.Children.Add(myTreeView);
    
                var asm = Assembly.GetAssembly(typeof(TreeViewItem));
    
                foreach (var type in asm.ExportedTypes)
                {
                    var node = new TreeViewItem() { Header = type.FullName, Style = this.myStyle };
                    myTreeView.Items.Add(node);
                    AppendItem(node, type);
                }
            }

    5. 定义一个ReLayout方法,用来调整TreeView控件在主窗体中的布局。并在“SizeChanged",”StateChanged“实践中调用该方法。

            private void ReLayout()
            {
                if (this.ActualHeight < 500)
                    return;
    
                if (this.ActualWidth < 500)
                    return;
    
                myTreeView.Height = this.ActualHeight - 50;
                myTreeView.Width = this.ActualWidth / 2;
            }

    6. 运行,效果如下。

    完整代码如下。

    using System;
    using System.Collections.Generic;
    using System.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.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Markup;
    using System.IO;
    using System.Reflection;
    
    namespace WpfApplication8
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private Style myStyle;
            private string stylePath = "..\\..\\CustomizedStyle.xml";
            private TreeView myTreeView = new TreeView();
    
            public MainWindow()
            {
                InitializeComponent();
    
                this.StyleParser();
            }
    
            private void StyleParser()
            {
                using (FileStream fileStream = new FileStream(this.stylePath, FileMode.Open, FileAccess.Read))
                {
                    this.myStyle = (Style)XamlReader.Load(fileStream);
                }
            }
    
            private void AppendItem(ItemsControl ctrl, Type type)
            {
                if (type.BaseType == null)
                    return;
    
                TreeViewItem myTreeViewItem = new TreeViewItem(){ Header = type.FullName, Style = this.myStyle};
                ctrl.Items.Add(myTreeViewItem);
                AppendItem(myTreeViewItem, type.BaseType);
            }
    
            private void Window_Loaded_1(object sender, RoutedEventArgs e)
            {
                ReLayout();
    
                myTreeView.Background = Brushes.SeaGreen;
                myTreeView.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                myTreeView.VerticalAlignment = System.Windows.VerticalAlignment.Top;
    
                myTreeView.Margin = new Thickness(5, 5, 0, 0);
                this.mainGrid.Children.Add(myTreeView);
    
                var asm = Assembly.GetAssembly(typeof(TreeViewItem));
    
                foreach (var type in asm.ExportedTypes)
                {
                    var node = new TreeViewItem() { Header = type.FullName, Style = this.myStyle };
                    myTreeView.Items.Add(node);
                    AppendItem(node, type);
                }
            }
    
            private void ReLayout()
            {
                if (this.ActualHeight < 500)
                    return;
    
                if (this.ActualWidth < 500)
                    return;
    
                myTreeView.Height = this.ActualHeight - 50;
                myTreeView.Width = this.ActualWidth / 2;
            }
    
            private void Window_StateChanged_1(object sender, EventArgs e)
            {
                ReLayout();
            }
    
            private void Window_SizeChanged_1(object sender, SizeChangedEventArgs e)
            {
                ReLayout();
            }
        }
    }
  • 相关阅读:
    POJ 3320 Jessica's Reading Problem
    引用参数和传值参数的区别
    IBM 的数据库Informix 常用代语法
    设计模式之原型模式
    UBoot中使用tftp下载文件出现错误TFTP error: 'Access violation' (2)的解决办法
    printf格式控制符的完整格式
    如何打印hostent结构体中的所有数据
    Informix 数据库客户端 dbvisualizer SQL Commander 乱码解决方案
    设计模式之模版方法模试
    nfs: server 192.168.37.200 not responding, still trying的解决办法
  • 原文地址:https://www.cnblogs.com/lucasluo/p/2627524.html
Copyright © 2011-2022 走看看