姑且喊它OptionForm


看到迅雷配置窗体,Alcohol 120%的配置也有这样的窗体,就连vs里面的这种布局的窗体都很多,不知道叫什么名字(各位大牛不要笑我啊),我暂且叫它Optionform或者SettingForm,感觉这种窗体还不不错,我有点想做一个才冲动了,我先来试试看:
在网上东找西找发现左边是一个treeview右边是一个panel,它的原理是点击左边树节点右边显示相关内容到panel里面,但是这里是显示的另外的窗体(我也是头次看到这样用窗体)

Demo1 OptionForm1:
我先建立了一个MainForm放了两个button这里有两种方式做的OptionForm,我为了让例子好看,就分别用一个按钮来显示一个OptionForm,好了现在新建一个OptionForm1

OK,这个OptionForm1左边放了一个treeview右边放了一个panel,为了好看我把迅雷上面的图片截了下来放到控件里面去了;然后新建了3个form:form1,form2,form3,我只做了迅雷配置里面的千3个标签,具体代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Demo1
{
    
public partial class OptionForm1 : Form
    
{
        
public OptionForm1()
        
{
            InitializeComponent();
        }

        
protected override void OnLoad(EventArgs e)
        
{
            treeView1.SelectedNode 
= treeView1.Nodes[0];
        }

        
        
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        
{
            
this.treeView1.SelectedNode.SelectedImageIndex = e.Node.ImageIndex;//保持图标不变
            panel1.Controls.Clear();//清除panel1内控件

            
switch (e.Node.Name)
            
{
                
case "N0":
                    Form1 form1 
= new Form1();               
                    label1.Text 
= "常规配置可设定迅雷的默认行为";
                    ShowForm(form1);
                    
break;
                
case "N1":
                    Form2 form2 
= new Form2();
                    label1.Text 
= "类别及目录选项可以帮助你方便的管理和下载";
                    ShowForm(form2);
                    
break;
                
case "N2":
                    Form3 form3 
= new Form3();
                    label1.Text 
= "任务默认属性配置可以让您设置新建任务的默认值";
                    ShowForm(form3);
                    
break;
            }

        }


        
public void ShowForm(Form leftForm)
        
{
            leftForm.FormBorderStyle 
= FormBorderStyle.None;
            leftForm.TopLevel 
= false;
            panel1.Controls.Add(leftForm);
            leftForm.Show();
        }


        
private void button1_Click(object sender, EventArgs e)
        
{
            
this.DialogResult = DialogResult.OK;
            
//TODO:
            this.Close();

        }


        
private void button2_Click(object sender, EventArgs e)
        
{
            
this.DialogResult = DialogResult.Cancel;
            
//TODO:
            this.Close();
        }

    }

}

这样只是一种显示方法,有个缺点就是如果有N个窗体显示在panel里面的话,我要new N次;

Demo1 OptionForm2:
在朋友的帮助下利用匿名委托(不知道说得对不对)用了另外一种方法实现:具体原理是:将第一次new的form放到list里面以后如果list里面存在这样的窗体就直接show如果没有则将这个窗体添加到list里面并show:代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Demo1
{
    
public partial class OptionForm2 : Form
    
{
        
public OptionForm2()
        
{
            InitializeComponent();
        }

      

        
protected override void OnLoad(EventArgs e)
        
{
            treeView1.SelectedNode 
= treeView1.Nodes[0];
        }


        List
<KeyValuePair<string, Form>> lstForms = new List<KeyValuePair<string, Form>>();
        
protected void LoadForm(string formName)
        
{
            panel1.Controls.Clear();

            Predicate
<KeyValuePair<string, Form>> find = delegate(KeyValuePair<string, Form> oneForm)
            
{
                
return oneForm.Key == formName;
            }
;

            KeyValuePair
<string, Form> findForm = lstForms.Find(find);
            
if (findForm.Key == null)
            
{
                Form form 
= (Activator.CreateInstance(Type.GetType("Demo1." + formName)) as Form);
                lstForms.Add(
new KeyValuePair<string, Form>(formName, form));
                form.Name 
= formName;
                form.FormBorderStyle 
= FormBorderStyle.None;
                form.TopLevel 
= false;
                panel1.Controls.Add(form);
                form.Show();
            }

            
else
            
{
                panel1.Controls.Add(findForm.Value);
            }

        }

        
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        
{
            
this.treeView1.SelectedNode.SelectedImageIndex = e.Node.ImageIndex;//保持图标不变
            panel1.Controls.Clear();//清除panel1内控件

            
switch (e.Node.Name)
            
{
                
case "N0":
                    label1.Text 
= "常规配置可设定迅雷的默认行为";
                    LoadForm(
"Form1");
                    
break;
                
case "N1":
                    label1.Text 
= "类别及目录选项可以帮助你方便的管理和下载";
                    LoadForm(
"Form2");
                    
break;
                
case "N2":
                    label1.Text 
= "任务默认属性配置可以让您设置新建任务的默认值";
                    LoadForm(
"Form3");
                    
break;
            }

        }


        
private void button1_Click(object sender, EventArgs e)
        
{
            
this.DialogResult = DialogResult.OK;
            
//TODO:
            for (int i = 0; i < lstForms.Count; i++)
            
{
                
switch (lstForms[i].Key)
                
{
                    
case "Form1":
                        ((Form1)lstForms[i].Value).SaveSetting();
                        
break;
                    
case "Form2":
                        ((Form2)lstForms[i].Value).SaveSetting();
                        
break;
                    
case "Form3":
                        ((Form3)lstForms[i].Value).SaveSetting();
                        
break;
                }

            }

            
this.Close();
        }


        
private void button2_Click(object sender, EventArgs e)
        
{
            
this.DialogResult = DialogResult.Cancel;
            
//TODO:
            this.Close();
        }



    }

}

这里加了保存的功能:在每个子窗体里面创建一个SaveSetting方法,然后点击保存时查找list里面的窗体,依次保存。
结果如下:


但是这里又有个问题:就是要转换成特定的窗体才能调用相应的保存设置的方法,于是又想到如果就调用依次save方法该多好啊,也许你已经想到用继承,不错,就是继承。

我是这样做的新建一个父窗体Base:Form里面有一个虚方法
public virtual void SaveSetting()
        { }
什么也没做,然后新建的 form1,form2,form3就继承baseform当然每个form里面要实现这个虚方法;好了看下代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Demo2
{
    
public partial class Form1 : Demo2.BaseForm
    
{
        
public Form1()
        
{
            InitializeComponent();
        }

        
protected override void OnLoad(EventArgs e)
        
{
            checkBox1.Checked 
= Properties.Settings.Default.F1Check1;
            checkBox2.Checked 
= Properties.Settings.Default.F1Check2;
            checkBox3.Checked 
= Properties.Settings.Default.F1Check3;
            numericUpDown1.Value 
= Properties.Settings.Default.F1Num1;
            numericUpDown2.Value 
= Properties.Settings.Default.F1Num2;
        }

        
public override void SaveSetting()
        
{
            Properties.Settings.Default.F1Check1 
= checkBox1.Checked;
            Properties.Settings.Default.F1Check2 
= checkBox2.Checked;
            Properties.Settings.Default.F1Check3 
= checkBox3.Checked;
            Properties.Settings.Default.F1Num1 
= numericUpDown1.Value;
            Properties.Settings.Default.F1Num2 
= numericUpDown2.Value;
            Properties.Settings.Default.Save();
        }

    }

}



当然optionform代码也要变下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Demo2
{
    
public partial class OptionForm : Form
    
{
        
public OptionForm()
        
{
            InitializeComponent();
        }


        
protected override void OnLoad(EventArgs e)
        
{
            treeView1.SelectedNode 
= treeView1.Nodes[0];
        }


        List
<KeyValuePair<string, BaseForm>> lstForms = new List<KeyValuePair<string, BaseForm>>();
        
protected void LoadForm(string formName)
        
{
            panel1.Controls.Clear();

            Predicate
<KeyValuePair<string, BaseForm>> find = delegate(KeyValuePair<string, BaseForm> oneForm)
            
{
                
return oneForm.Key == formName;
            }
;

            KeyValuePair
<string, BaseForm> findForm = lstForms.Find(find);
            
if (findForm.Key == null)
            
{
                BaseForm form 
= (Activator.CreateInstance(Type.GetType("Demo2." + formName)) as BaseForm);
                lstForms.Add(
new KeyValuePair<string, BaseForm>(formName, form));
                form.Name 
= formName;
                form.FormBorderStyle 
= FormBorderStyle.None;
                form.TopLevel 
= false;
                panel1.Controls.Add(form);
                form.Show();
            }

            
else
            
{
                panel1.Controls.Add(findForm.Value);
            }

        }

        
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        
{
            
this.treeView1.SelectedNode.SelectedImageIndex = e.Node.ImageIndex;//保持图标不变
            panel1.Controls.Clear();//清除panel1内控件

            
switch (e.Node.Name)
            
{
                
case "N0":
                    label1.Text 
= "常规配置可设定迅雷的默认行为";
                    LoadForm(
"Form1");
                    
break;
                
case "N1":
                    label1.Text 
= "类别及目录选项可以帮助你方便的管理和下载";
                    LoadForm(
"Form2");
                    
break;
                
case "N2":
                    label1.Text 
= "任务默认属性配置可以让您设置新建任务的默认值";
                    LoadForm(
"Form3");
                    
break;
            }

        }


        
private void button1_Click(object sender, EventArgs e)
        
{
            
this.DialogResult = DialogResult.OK;
            
//TODO:
            for (int i = 0; i < lstForms.Count; i++)
            
{
                lstForms[i].Value.SaveSetting();
            }

            
this.Close();
        }


        
private void button2_Click(object sender, EventArgs e)
        
{            
            
for (int i = 0; i < lstForms.Count; i++)
            
{
                lstForms[i].Value.SaveSetting();
            }

        }


        
private void button3_Click(object sender, EventArgs e)
        
{
            
this.DialogResult = DialogResult.Cancel;
            
//TODO:
            this.Close();
        }



    }

}

第一次在博客园写文章,各位大牛些多多指教。

====================================================
早上来公司修改了下,原来图片大了就传不上来
posted @ 2008-06-26 22:20  Simens  阅读(1721)  评论(12编辑  收藏  举报