一个明确用户界面需求的想法
在應(yīng)用程序開發(fā)中,需求不清晰從而導(dǎo)致需求變更是一個(gè)讓所有人深惡痛絕的事情,用戶界面也是其中很重要的部分。之所以用戶的需求不清晰是因?yàn)樵诤芏鄷r(shí)候,用戶的腦海中往往只會(huì)構(gòu)思和想象用戶界面的一部分,他只能告訴你他想要的軟件大概是個(gè)什么樣子,有哪些功能和操作;你們也許會(huì)在紙上或者通過(guò)繪圖工具繪制一些用戶界面,這也不夠準(zhǔn)確直觀;而讓用戶自己使用VisualStudio設(shè)計(jì)他想要的界面更是不現(xiàn)實(shí)的。所以,我們是不是可以提供一個(gè)簡(jiǎn)單的界面設(shè)計(jì)器,讓用戶自己設(shè)計(jì)他的一部分界面,從而使得他的需求更明確些呢?
Microsoft Expression Blend就是這樣的一個(gè)軟件,但是Blend還是太專業(yè)復(fù)雜了些,用戶肯定不愿意去學(xué)習(xí)使用這樣的軟件;而我們自己做一個(gè)界面設(shè)計(jì)器也代價(jià)太大,使用第三方開發(fā)的軟件也需要購(gòu)買成本和學(xué)習(xí)成本。所以,我想我們是不是可以先做好一個(gè)大概的界面原型,然后讓用戶自己設(shè)置更改這個(gè)界面原型?
我設(shè)想的流程是這樣的:
1.??開發(fā)人員和客戶先討論界面大概做成什么樣子。
2.??開發(fā)人員做出一個(gè)界面的原型,就是一個(gè)From。
3.? 客戶將Form跑起來(lái),并能夠自定義該Form,能夠給Form及Form上的元素加注釋。
4.??客戶將自定義的Form保存,開發(fā)人員拿到結(jié)果后再做一個(gè)原型…
關(guān)于界面原型的一些初步構(gòu)想:
1、 只做一個(gè)純粹的界面,界面上不需要加事件處理函數(shù)等,除非會(huì)彈出另外一個(gè)需要和客戶確認(rèn)的Dialog/Form。
2、 在希望用戶自定義的地方(一般而言是Form或者某個(gè)控件)添加ContextMenu或者其它可以定制控件的能力,但是添加的設(shè)計(jì)功能不應(yīng)該影響用戶對(duì)于界面的直觀感受,所以直接暴露在用戶眼中的部分越少越好
3、 應(yīng)當(dāng)給用戶設(shè)置每一個(gè)控件注釋的能力,注釋中包含開發(fā)人員的解釋以及客戶的解釋,比如說(shuō)這個(gè)按鈕點(diǎn)擊以后會(huì)發(fā)生什么事,而客戶對(duì)于無(wú)法設(shè)置的地方也可以加上他自己的想法。
關(guān)于如何保存用戶對(duì)界面的修改:我們可以把Form對(duì)象序列化成源代碼,就像在VisualStudio的設(shè)計(jì)器中設(shè)計(jì)Form那樣。至于如何將一個(gè)Form序列化成源代碼,請(qǐng)參照從Component對(duì)象到CodeDom——舞動(dòng)你的Code系列(1)
開發(fā)人員拿到源代碼后,根據(jù)客戶的改動(dòng)以及注釋再做一個(gè)更接近用戶想法的原型,可以再給客戶自己修改直到滿意為止。
以下是本人使用一個(gè)ToolStrip實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的Demo,用戶可以使用ToolStrip定制Form上任意Control的注釋、字體、位置、尺寸以及前景色背景色。當(dāng)用戶沒有點(diǎn)擊任何Control的時(shí)候:
??
用戶點(diǎn)擊了‘客戶名’這個(gè)Label后:
??
設(shè)置字體為‘黑體’,字號(hào)為‘10’,背景色,前景色:
??????
這個(gè)ToolStrip已經(jīng)被包裝成了一個(gè)Control,只需要把它拖到任意Form上,并在Form上接收所有Control的MouseClick事件,并把點(diǎn)擊的Control設(shè)置給該ToolStrip的SelectedControl屬性即可。
ToolStrip的源碼:
代碼 using System;using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace GrapeCity.Cylj.ControlSetToolBar
{
public class ControlSetToolBar : ToolStrip
{
public ControlSetToolBar()
{
this.InitializeComponent();
System.Drawing.Text.InstalledFontCollection fonts = new System.Drawing.Text.InstalledFontCollection();
foreach (System.Drawing.FontFamily font in fonts.Families)
{
this.font.Items.Add(font.Name);
}
}
private Control selectedControl;
public Control SelectedControl
{
get
{
return selectedControl;
}
set
{
if (value == null)
{
this.Enabled = false;
this.comments.Text = "";
this.font.Text = "";
this.fontSize.Text = "";
this.xLocation.Text = "";
this.yLocation.Text = "";
this.width.Text = "";
this.height.Text = "";
}
if (this.selectedControl != value)
{
this.Enabled = true;
selectedControl = value;
string comments = selectedControl.Tag == null ? "" : selectedControl.Tag.ToString();
if (string.IsNullOrEmpty(comments))
{
this.comments.TextChanged -= new EventHandler(comments_TextChanged);
this.comments.Text = "請(qǐng)?jiān)诖溯斎胱⑨?/span>";
this.comments.ForeColor = Color.Gray;
this.comments.TextChanged += new EventHandler(comments_TextChanged);
}
else
{
this.comments.Text = comments;
this.comments.ForeColor = SystemColors.WindowText;
}
this.font.Text = selectedControl.Font.Name;
this.fontSize.Text = (int)Math.Round(selectedControl.Font.Size) + "";
this.xLocation.Text = selectedControl.Location.X + "";
this.yLocation.Text = selectedControl.Location.Y + "";
this.width.Text = selectedControl.Width + "";
this.height.Text = selectedControl.Height + "";
this.backColor.BackColor = selectedControl.BackColor;
this.backColor.ForeColor = selectedControl.ForeColor;
this.foreColor.BackColor = selectedControl.BackColor;
this.foreColor.ForeColor = selectedControl.ForeColor;
}
}
}
private ToolStripTextBox comments;
private ToolStripLabel toolStripLabel1;
private ToolStripLabel toolStripLabel2;
private ToolStripComboBox font;
private ToolStripLabel toolStripLabel3;
private ToolStripComboBox fontSize;
private ToolStripLabel toolStripLabel4;
private ToolStripTextBox xLocation;
private ToolStripLabel toolStripLabel5;
private ToolStripTextBox yLocation;
private ToolStripLabel toolStripLabel6;
private ToolStripTextBox width;
private ToolStripLabel toolStripLabel7;
private ToolStripTextBox height;
private ToolStripButton backColor;
private ToolStripButton foreColor;
private ToolStripSeparator toolStripSeparator1;
private ToolStripSeparator toolStripSeparator2;
private ToolStripSeparator toolStripSeparator3;
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ControlSetToolBar));
this.comments = new System.Windows.Forms.ToolStripTextBox();
this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel();
this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel();
this.font = new System.Windows.Forms.ToolStripComboBox();
this.toolStripLabel3 = new System.Windows.Forms.ToolStripLabel();
this.fontSize = new System.Windows.Forms.ToolStripComboBox();
this.toolStripLabel4 = new System.Windows.Forms.ToolStripLabel();
this.xLocation = new System.Windows.Forms.ToolStripTextBox();
this.toolStripLabel5 = new System.Windows.Forms.ToolStripLabel();
this.yLocation = new System.Windows.Forms.ToolStripTextBox();
this.toolStripLabel6 = new System.Windows.Forms.ToolStripLabel();
this.width = new System.Windows.Forms.ToolStripTextBox();
this.toolStripLabel7 = new System.Windows.Forms.ToolStripLabel();
this.height = new System.Windows.Forms.ToolStripTextBox();
this.backColor = new System.Windows.Forms.ToolStripButton();
this.foreColor = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new ToolStripSeparator();
this.toolStripSeparator2 = new ToolStripSeparator();
this.toolStripSeparator3 = new ToolStripSeparator();
this.SuspendLayout();
//
// toolStripTextBox1
//
this.comments.Name = "comments";
this.comments.Size = new System.Drawing.Size(100, 21);
this.comments.Text = "請(qǐng)?jiān)诖溯斎胱⑨?/span>";
this.comments.TextChanged += new EventHandler(comments_TextChanged);
//
// toolStripLabel1
//
this.toolStripLabel1.Name = "toolStripLabel1";
this.toolStripLabel1.Size = new System.Drawing.Size(0, 22);
//
// toolStripLabel2
//
this.toolStripLabel2.Name = "toolStripLabel2";
this.toolStripLabel2.Size = new System.Drawing.Size(29, 12);
this.toolStripLabel2.Text = "字體";
//
// toolStripComboBox1
//
this.font.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.font.Name = "font";
this.font.Size = new System.Drawing.Size(75, 20);
this.font.TextChanged += new EventHandler(font_TextChanged);
//
// toolStripLabel3
//
this.toolStripLabel3.Name = "toolStripLabel3";
this.toolStripLabel3.Size = new System.Drawing.Size(29, 12);
this.toolStripLabel3.Text = "字號(hào)";
this.fontSize.TextChanged += new EventHandler(fontSize_TextChanged);
//
// toolStripComboBox2
//
this.fontSize.Items.AddRange(new object[] {
"8",
"9",
"10",
"12",
"14",
"16"});
this.fontSize.Name = "toolStripComboBox2";
this.fontSize.Size = new System.Drawing.Size(75, 20);
//
// toolStripLabel4
//
this.toolStripLabel4.Name = "toolStripLabel4";
this.toolStripLabel4.Size = new System.Drawing.Size(17, 12);
this.toolStripLabel4.Text = "X:";
//
// toolStripTextBox2
//
this.xLocation.Name = "toolStripTextBox2";
this.xLocation.Size = new System.Drawing.Size(30, 21);
this.xLocation.TextChanged += new EventHandler(xLocation_TextChanged);
//
// toolStripLabel5
//
this.toolStripLabel5.Name = "toolStripLabel5";
this.toolStripLabel5.Size = new System.Drawing.Size(17, 12);
this.toolStripLabel5.Text = "Y:";
//
// toolStripTextBox3
//
this.yLocation.Name = "toolStripTextBox3";
this.yLocation.Size = new System.Drawing.Size(30, 21);
this.yLocation.TextChanged += new EventHandler(yLocation_TextChanged);
//
// toolStripLabel6
//
this.toolStripLabel6.Name = "toolStripLabel6";
this.toolStripLabel6.Size = new System.Drawing.Size(23, 12);
this.toolStripLabel6.Text = "寬:";
//
// toolStripTextBox4
//
this.width.Name = "toolStripTextBox4";
this.width.Size = new System.Drawing.Size(30, 21);
this.width.TextChanged += new EventHandler(width_TextChanged);
//
// toolStripLabel7
//
this.toolStripLabel7.Name = "toolStripLabel7";
this.toolStripLabel7.Size = new System.Drawing.Size(23, 12);
this.toolStripLabel7.Text = "高:";
//
// toolStripTextBox5
//
this.height.Name = "toolStripTextBox5";
this.height.Size = new System.Drawing.Size(30, 21);
this.height.TextChanged += new EventHandler(height_TextChanged);
//
// toolStripButton1
//
this.backColor.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.backColor.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
this.backColor.ImageTransparentColor = System.Drawing.Color.Magenta;
this.backColor.Name = "toolStripButton1";
this.backColor.Size = new System.Drawing.Size(26, 22);
this.backColor.Text = "背景色";
this.backColor.Click += new EventHandler(backColor_Click);
this.backColor.Margin = new Padding(0, 0, 3, 0);
//
// toolStripButton2
//
this.foreColor.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.foreColor.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
this.foreColor.ImageTransparentColor = System.Drawing.Color.Magenta;
this.foreColor.Name = "toolStripButton2";
this.foreColor.Size = new System.Drawing.Size(26, 22);
this.foreColor.Text = "前景色";
this.foreColor.Click += new EventHandler(foreColor_Click);
//
// ControlSetToolBar
//
this.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripLabel1,
this.comments,
this.toolStripSeparator1,
this.toolStripLabel2,
this.font,
this.toolStripLabel3,
this.fontSize,
this.toolStripLabel4,
this.toolStripSeparator3,
this.xLocation,
this.toolStripLabel5,
this.yLocation,
this.toolStripLabel6,
this.width,
this.toolStripLabel7,
this.height,
this.toolStripSeparator3,
this.backColor,
this.foreColor});
this.ResumeLayout(false);
}
void foreColor_Click(object sender, EventArgs e)
{
Color newColor;
if (SetColor(this.selectedControl.ForeColor, out newColor))
{
this.selectedControl.ForeColor = newColor;
this.foreColor.ForeColor = newColor;
this.backColor.ForeColor = newColor;
}
}
void backColor_Click(object sender, EventArgs e)
{
Color newColor;
if (SetColor(this.selectedControl.BackColor, out newColor))
{
this.selectedControl.BackColor = newColor;
this.foreColor.BackColor = newColor;
this.backColor.BackColor = newColor;
}
}
private bool SetColor(Color oldColor, out Color newColor)
{
ColorDialog dialog = new ColorDialog();
dialog.Color = oldColor;
DialogResult result = dialog.ShowDialog(this.selectedControl.FindForm());
if (result == DialogResult.OK || result == DialogResult.Yes)
{
newColor = dialog.Color;
return true;
}
newColor = oldColor;
return false;
}
void height_TextChanged(object sender, EventArgs e)
{
if (this.selectedControl == null)
{
return;
}
int intValue;
bool success = Int32.TryParse(this.height.Text, out intValue);
if (!success)
{
this.height.Text = this.selectedControl.Height + "";
return;
}
this.selectedControl.Height = intValue;
}
void width_TextChanged(object sender, EventArgs e)
{
if (this.selectedControl == null)
{
return;
}
int intValue;
bool success = Int32.TryParse(this.width.Text, out intValue);
if (!success)
{
this.width.Text = this.selectedControl.Width + "";
return;
}
this.selectedControl.Width = intValue;
}
void yLocation_TextChanged(object sender, EventArgs e)
{
if (this.selectedControl == null)
{
return;
}
int intValue;
bool success = Int32.TryParse(this.yLocation.Text, out intValue);
if (!success)
{
this.yLocation.Text = this.selectedControl.Location.Y + "";
return;
}
this.selectedControl.Location = new System.Drawing.Point(this.selectedControl.Location.X, intValue);
}
void xLocation_TextChanged(object sender, EventArgs e)
{
if (this.selectedControl == null)
{
return;
}
int intValue;
bool success = Int32.TryParse( this.xLocation.Text, out intValue);
if(!success)
{
this.xLocation.Text = this.selectedControl.Location.X + "";
return;
}
this.selectedControl.Location = new System.Drawing.Point(intValue, this.selectedControl.Location.Y);
}
void fontSize_TextChanged(object sender, EventArgs e)
{
if (this.selectedControl == null)
{
return;
}
int intValue;
bool success = Int32.TryParse(this.fontSize.Text, out intValue);
if (!success)
{
this.fontSize.Text = Math.Round(this.selectedControl.Font.Size) + "";
return;
}
this.selectedControl.Font = new System.Drawing.Font(this.font.Text, intValue);
}
void font_TextChanged(object sender, EventArgs e)
{
if (this.selectedControl == null)
{
return;
}
if (this.font.SelectedItem != null)
{
this.selectedControl.Font = new System.Drawing.Font(this.font.SelectedItem.ToString(), this.selectedControl.Font.Size);
}
}
void comments_TextChanged(object sender, EventArgs e)
{
if (this.selectedControl == null)
{
return;
}
this.selectedControl.Tag = this.comments.Text;
this.comments.ToolTipText = this.comments.Text;
}
}
}
Form的源碼:
代碼 public Form1()
{
InitializeComponent();
AddEvents(this);
}
private void AddEvents(Control parentControl)
{
foreach (Control control in parentControl.Controls)
{
if (control == this.controlSetToolBar1)
{
continue;
}
control.MouseClick += new MouseEventHandler(control_MouseClick);
AddEvents(control);
}
}
void control_MouseClick(object sender, MouseEventArgs e)
{
Control control = sender as Control;
if (control != null)
{
this.controlSetToolBar1.SelectedControl = control;
}
}
?
?
?
當(dāng)然,這只是本人的一個(gè)構(gòu)想,尚沒有成功的商業(yè)案例。如何您對(duì)這個(gè)想法感興趣或者您還有些別的更好的做法,請(qǐng)回帖或者直接給我發(fā)信討論。
本篇是從Component對(duì)象到CodeDom——舞動(dòng)你的Code系列(1)的應(yīng)用,可以算作舞動(dòng)你的Code系列(1.1)。如果你對(duì)設(shè)計(jì)器、VisualStudio擴(kuò)展、序列化、控件設(shè)計(jì)等相關(guān)技術(shù)感興趣,歡迎訂閱收藏本博客。
轉(zhuǎn)載于:https://www.cnblogs.com/VisualStudioDesigner/archive/2010/09/21/1832393.html
總結(jié)
以上是生活随笔為你收集整理的一个明确用户界面需求的想法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 企查查app如何更改手机号号码(企业工商
- 下一篇: QQ无法安装,不用着急,用毒霸2011来