[原创] 算法之递归(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();
        }
    }
}
时间: 2024-10-09 12:24:28

[原创] 算法之递归(4)- 应用的相关文章

[原创] 算法之递归(3)- 链表操作

算法之递归(3)- 链表操作 递归(2)尝试了一个单链表的遍历,同时又分析了如何添加自己的操作,是在递归调用之前,还是在递归调用之后. 今天,打算将问题深入一下,即添加相应的操作在递归的过程中. (免责声明:下面的解法纯属娱乐 ,另外,示例代码未经编译和调试,许多想法未经实践验证.) 查找链表当中倒数第N个节点. 解法一 逐层递归,遍历到最后一个节点,并从返回的节点一次向后递归,遍历N次,找到倒数第N个节点. private LNode targetNode = null; private LN

[原创] 算法之递归(2)- 链表遍历

算法之递归(2)- 链表遍历 在递归(1)中,简单的介绍了递归的思想,并且通过一个例子简单阐述了递归是如何工作的,并且递归的实现是以线性结构来表示的.之所以用线性的,是因为其易于理解:如果使用树结构,将加大对问题的难度,不利于初学者理解递归的思想. 为什么用递归 关 于为什么用递归,我个人的理解是递归不要违背算法的初衷,即期待传入xxx值,加工后返回xxx值.不要为了递归而递归,容易造成对函数语义的奇异.另 外,通过递归,可以让代码更加整洁,短小,精湛,优美.当然,还会存在一定程度的性能损耗:不

[原创] 算法之递归(1)

算法之递归(1) 最近事情太多了,很少有时间可以完全静下来认真研究一些东西:每当专注的写代码的时候,总是被其他事情打断.还好,礼拜天来了,总算可以抽出一些时间了J <代码之美>第一章有一个关于模式匹配的问题,即根据正则表达式在相应的文本中找到匹配的值,找到返回1,没找到返回0.撇开具体的实现,里面优美的递归调用倒是深深地吸引了我.于是,我开始重新思考递归,毕竟有些细节之前的思考还不够到位. 什么是递归 我的印象中的递归是函数调用自身来完成预先定义的操作.当然,实际涉及的内容更多,比如退出递归的

java数据结构与算法之递归思维(让我们更通俗地理解递归)

[版权申明]转载请注明出处(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53452971 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) java数据结构与算法之栈(Stack)设计与实现 j

Java数据结构和算法之递归

四.递归 递归是函数调用自身的一种特殊的编程技术,其应用主要在以下几个方面:   阶乘 在java当中的基本形式是: Public  void  mothed(int n){//当满足某条件时: Mothed(n‐1): } 递归二分查找 Java二分查找实现,欢迎大家提出交流意见.  /** *名称:BinarySearch *功能:实现了折半查找(二分查找)的递归和非递归算法. *说明: *     1.要求所查找的数组已有序,并且其中元素已实现Comparable<T>接口,如Integ

数据结构与算法5: 递归(Recursion)

数据结构与算法5: 递归(Recursion) 写在前面 <软件随想录:程序员部落酋长Joel谈软件>一书中<学校只教java的危险性>一章提到,大学计算机系专业课有两个传统的知识点,但许多人从来都没搞懂过,那就是指针和递归.我也很遗憾没能早点熟练掌握这两个知识点.本节一些关键知识点和部分例子,都整理自教材或者网络,参考资料列在末尾.如果错误请纠正我. 思考列表: 1)什么程序具有递归解决的潜质? 2)递归还是非递归算法,怎么选择? 3)递归程序构造的一般模式 1.递归定义 首要引

二分查找算法(递归与非递归两种方式)

首先说说二分查找法. 二分查找法是对一组有序的数字中进行查找,传递相应的数据,进行比较查找到与原数据相同的数据,查找到了返回1,失败返回对应的数组下标. 采用非递归方式完成二分查找法.java代码如下所示. /* * 非递归二分查找算法 * 参数:整型数组,需要比较的数. */ public static int binarySearch(Integer[]srcArray,int des){ //第一个位置. int low=0; //最高位置.数组长度-1,因为下标是从0开始的. int h

全排列算法的递归与非递归实现

全排列算法的递归与非递归实现 全排列算法是常见的算法,用于求一个序列的全排列,本文使用C语言分别用递归与非递归两种方法实现,可以接受元素各不相同的输入序列. 题目来自leetcode: Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3

编程算法 - 背包问题(递归) 代码(C)

背包问题(递归) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有n个重量和价值分别为w,v的物品, 从这些物品中挑选出总重量不超过W的物品, 求所有挑选方案中价值总和的最大值. 即经典动态规划问题. 可以使用深度优先搜索, 把每个部分都遍历到, 选取最优解, 但不是最好的方法. 代码: /* * main.cpp * * Created on: 2014.7.17 * Author: spike */ /*eclipse cdt, gc