您的位置:首页 > 其它

跟着小王学习wpf之八 Grid

2011-04-04 00:34 363 查看
下面我们来讨论一个另一个布局控件:Grid。

Grid和以上我们看到的其他布局控件有些不同,首先他只用来布局,它也许是最有用的布局控件:

他可以随意的列数和行数:

每列的行高可以通过以下方式来确定:

1:设定一个固定的长度值

2:设定为这一行中所有子元素中最高的那个元素的行高。

3:设定为剩余空间的高度。

列宽也是如此规则。

public MyWindow()

{

Title = "WrapPanel box";

Grid grid = new Grid();

Content = grid;

grid.ShowGridLines = true;

RowDefinition rowdef = new RowDefinition();

rowdef.Height = new GridLength(37, GridUnitType.Star);

grid.RowDefinitions.Add(rowdef);

rowdef = new RowDefinition();

rowdef.Height = new GridLength(33,GridUnitType.Star);

grid.RowDefinitions.Add(rowdef);

rowdef = new RowDefinition();

rowdef.Height = new GridLength(150);

grid.RowDefinitions.Add(rowdef);

rowdef = new RowDefinition();

rowdef.Height = new GridLength(30,GridUnitType.Star);

grid.RowDefinitions.Add(rowdef);

Uri uri = new Uri("pack://application:,,,/1.png");

BitmapImage bi = new BitmapImage(uri);

Image img = new Image();

img.Margin = new Thickness(0, 10, 0, 0);

img.Source = bi;

grid.Children.Add(img);

Grid.SetRow(img, 0);

}

仅仅设置了4个行:

当我们给它添加上列:

ColumnDefinition columndef = new ColumnDefinition();

columndef.Width = new GridLength(50, GridUnitType.Star);

grid.ColumnDefinitions.Add(columndef);

columndef = new ColumnDefinition();

columndef.Width = GridLength.Auto;

grid.ColumnDefinitions.Add(columndef);

columndef = new ColumnDefinition();

columndef.Width = new GridLength(50, GridUnitType.Star);

grid.ColumnDefinitions.Add(columndef);

然后让这个图形定位在

Grid.SetRow(img, 0);

Grid.SetColumn(img, 1);

这个是运行后产生的图像。

public MyWindow()

{

Title = "WrapPanel box";

WrapPanel wrap = new WrapPanel();

SizeToContent = SizeToContent.WidthAndHeight;

Grid grid = new Grid();

wrap.Children.Add(grid);

Content = wrap;

grid.ShowGridLines = true;

for(int i=0;i<6;i++)

{

RowDefinition rowdef = new RowDefinition();

rowdef.Height =GridLength.Auto;

grid.RowDefinitions.Add(rowdef);

}

for (int j = 0; j < 4;j++ )

{

ColumnDefinition columndef = new ColumnDefinition();

if (j==1)

{

columndef.Width = new GridLength(100, GridUnitType.Star);

}

else

{

columndef.Width = GridLength.Auto;

}

grid.ColumnDefinitions.Add(columndef);

}

string[] lablestr = {

"_Frist name:","_last name:","_Social security number:","_Credit card number","_Other personl Staff"

};

for (int i = 0; i < lablestr.Length;i++ )

{

Label lbl = new Label();

lbl.Content = lablestr[i];

lbl.VerticalContentAlignment = VerticalAlignment.Center;

grid.Children.Add(lbl);

Grid.SetRow(lbl, i);

Grid.SetColumn(lbl, 0);

TextBox txt = new TextBox();

grid.Children.Add(txt);

txt.Margin = new Thickness(5);

Grid.SetRow(txt, i);

Grid.SetColumn(txt, 1);

Grid.SetColumnSpan(txt, 3);

}

Button btn = new Button();

btn.Content = "Submit";

btn.IsDefault = true;

btn.Click += delegate

{

Close();

};

grid.Children.Add(btn);

Grid.SetRow(btn, 5);

Grid.SetColumn(btn, 2);

btn = new Button();

btn.Content = "Close";

btn.IsCancel = true;

btn.Click += delegate

{

Close();

};

grid.Children.Add(btn);

Grid.SetRow(btn, 5);

Grid.SetColumn(btn, 4);

grid.Children[0].Focus();

}

我们定义了一个6行4列的Grid但是只显示出

因为我们给其他没有显示出来的列选择的auto。

如果我们需要让整个窗体的布局可以移动,那么可能就需要一个GridSplitter:

public MyWindow()

{

Title = "WrapPanel box";

SizeToContent = SizeToContent.WidthAndHeight;

Grid grid = new Grid();

Content = grid;

grid.ShowGridLines = true;

for(int i=0;i<3;i++)

{

grid.RowDefinitions.Add(new RowDefinition());

grid.ColumnDefinitions.Add(new ColumnDefinition());

}

for (int i = 0; i < 3;i++ )

{

for (int j = 0; j < 3;j++ )

{

Button btn = new Button();

btn.Content = "Button" + i.ToString("00") + j.ToString("00");

grid.Children.Add(btn);

Grid.SetRow(btn, i);

Grid.SetColumn(btn, j);

btn.Margin = new Thickness(5);

}

}

GridSplitter gridspter = new GridSplitter();

gridspter.Width = 6;

grid.Children.Add(gridspter);

Grid.SetRow(gridspter, 1);

Grid.SetColumn(gridspter, 1);

}

一开始是无法拖动的,是因为我们选择的是SizeToContent = SizeToContent.WidthAndHeight;让窗体来适应内容大小,而这些button也是以最小形态显示的。只有再这个窗体变化后才能体现出来效果。

当然最好让这个拖动条贯穿整个窗体:

Grid.SetRow(gridspter, 0);

Grid.SetRowSpan(gridspter, 3);

我们要看到它以区分他和其他控件,方便我们说明问题:

gridspter.Background = Brushes.Red;

gridspter.HorizontalAlignment属性可以选择right,left,center。默认的是right,这样的话拖动这个分割条将会影响当前格子以及右边相邻的格子的宽度。如果设置为left则反之:影响当前格子以及左边相邻的格子的宽度。当然最正常的方式应该是center,这样将会影响左右两边相邻格子的宽度,而当前格子宽度不变:

gridspter.HorizontalAlignment = HorizontalAlignment.Center;

当然你也可以通过其他的方式来改变这个效果:比如说

gridspter.ResizeBehavior = GridResizeBehavior.CurrentAndNext;

这样的话程序又只影响了当前格子和右边相邻的格子。

GridResizeBehavior.CurrentAndNext;//当前格子以及下一个

GridResizeBehavior.PreviousAndCurrent;//前一个格子和下一个格子

GridResizeBehavior.PreviousAndNext;//前一个和当前格子

GridResizeBehavior.BasedOnAlignment;//根据HorizontalAlignment和VerticalAlignment决定

我们可以想象,如果我们设置了VerticalAlignment,可能出现的就是一个水平的拖动条:

gridspter.VerticalAlignment = VerticalAlignment.Bottom;

Grid.SetColumn(gridspter, 0);

Grid.SetRow(gridspter, 1);

Grid.SetColumnSpan(gridspter, 3);

但是,运行后的结果是,拖动条没有出现,为什么呢?

因为HorizontalAlignment默认为right而不是Stretch。如果你要求一个拖动条横跨3列又出现在最右边,而且水平出现在最下面,那么它将会是一个点。所以我们没有办法看到:

因此需要设置HorizontalAlignment为Stretch(根据实际需要填充)。

gridspter.HorizontalAlignment = HorizontalAlignment.Stretch;

但是我们执行了这个语句之后依然没有出现水平的拖动条,这是我非常的疑惑,查阅了大量的资料都没有发现问题所在,最后我把无关语句一条一条的删除,直到这一句:

gridspter.Width = 6;

设置拖动条的width?宽度?如果你设置一个拖动条的宽度的话 那么这个拖动条一定是一个竖直的,如果你想要一个水平的拖动条,就不要设置这个属性。

在上面这个问题上我竟然徘徊了将近半个小时。

问题又来了,当我们拖动这个窗口后 这个中间这一行我们应该是让它适应内容大小才好。或者我们根本不要这么做,为此我们将Grid的构造过程改为如下情况:

for(int i=0;i<3;i++)

{

RowDefinition trow = new RowDefinition();

if (i==1)

{

trow.Height = GridLength.Auto;

}

else

{

trow.Height = new GridLength(50, GridUnitType.Star);

}

grid.RowDefinitions.Add(trow);

ColumnDefinition tcolmn = new ColumnDefinition();

tcolmn.Width = new GridLength(33, GridUnitType.Star);

grid.ColumnDefinitions.Add(tcolmn);

}

显示结果符合我们的预期。

public MyWindow()

{

Title = "WrapPanel box";

SizeToContent = SizeToContent.WidthAndHeight;

Grid grid = new Grid();

Content = grid;

grid.ShowGridLines = true;

for(int i=0;i<3;i++)

{

RowDefinition trow = new RowDefinition();

ColumnDefinition tcolmn = new ColumnDefinition();

if (i==1)

{

trow.Height = GridLength.Auto;

tcolmn.Width = GridLength.Auto;

}

else

{

trow.Height = new GridLength(50, GridUnitType.Star);

tcolmn.Width = new GridLength(50, GridUnitType.Star);

}

grid.RowDefinitions.Add(trow);

grid.ColumnDefinitions.Add(tcolmn);

}

for (int i = 0; i < 3;i++ )

{

for (int j = 0; j < 3;j++ )

{

if (i==1||j==1)

{

continue;

}

Button btn = new Button();

btn.Content = "Button" + i.ToString("00") + j.ToString("00");

grid.Children.Add(btn);

Grid.SetRow(btn, i);

Grid.SetColumn(btn, j);

btn.Margin = new Thickness(5);

}

}

GridSplitter gridspter = new GridSplitter();

gridspter.Height = 6;

gridspter.HorizontalAlignment = HorizontalAlignment.Stretch;

gridspter.ResizeBehavior = GridResizeBehavior.PreviousAndNext;

gridspter.Background = Brushes.Red;

Grid.SetColumn(gridspter, 0);

Grid.SetRow(gridspter, 1);

Grid.SetColumnSpan(gridspter, 3);

grid.Children.Add(gridspter);

GridSplitter gridspter1 = new GridSplitter();

gridspter1.Width = 6;

gridspter1.HorizontalAlignment = HorizontalAlignment.Center;

gridspter1.ResizeBehavior = GridResizeBehavior.PreviousAndNext;

gridspter1.Background = Brushes.Red;

Grid.SetColumn(gridspter1, 1);

Grid.SetRow(gridspter1, 0);

Grid.SetRowSpan(gridspter1, 3);

grid.Children.Add(gridspter1);

}

构造一个3*3的gird中间一个一列和一行专门用来放拖动条。

将gridspter.ShowsPreview = true;可以看到预计将要移动的位置

而且你还可以使用上下左右键来操作,前提是必须让这个空间获取焦点。

下面我们来讨论ScrollBar:

当你点击一个Scrollbar中的上下两个按钮,他的value属性将会变化一个Smallchange单位,当然这个value属性的值是必须介于minimun和maximun这两个属性之间的。当你点击了thumb,也会改变value属性的值,这个值是由lagerchange所决定。注意这里的Smallchange和lagerchange都是它的属性,单位均为double。

ScrollBar从他的父类Rangebase类继承了valuechange事件,他自己也实现了Scroll事件。在刚才的程序中添加以下语句:

ScrollBar hsrocll = new ScrollBar();

ScrollBar vsroll = new ScrollBar();

grid.Children.Add(hsrocll);

grid.Children.Add(vsroll);

Grid.SetRow(hsrocll, 0);

Grid.SetColumn(hsrocll, 2);

Grid.SetRowSpan(hsrocll, 3);

Grid.SetRow(vsroll, 2);

Grid.SetColumn(vsroll, 0);

Grid.SetColumnSpan(vsroll, 3);

按照预期应该出现两个滚动条:

竖直滚动条符合预期,但是水平的滚动条还是一个竖直的,说明滚动条默认是竖直的,如何设置为水平的呢?

vsroll.Orientation = Orientation.Horizontal;

达到了预期,但是这个滚动条没有贴着窗体。

if (i==2)

{

trow.Height = GridLength.Auto;

tcolmn.Width = GridLength.Auto;

}

设置第三行和第三列自动。

但是问题又来了,这两个滚动条在右下角重合了,所有将竖直滚动条的右下角弄没有了。由于一般情况下是边界点不用的。所有该程序:

Grid.SetRowSpan(hsrocll, 2); Grid.SetColumnSpan(vsroll, 2);让两个滚动条均只延伸到前一个格子:

最后一个格子一般用来显示程序的运行状态,或者显示桌面。

下面我们看一个使用Srocllbar的例子:

class MyWindow:Window

{

Panel pancel;

ScrollBar[] scrolls = new ScrollBar[3];

TextBlock[] TextBlocks = new TextBlock[3];

[STAThread]

static void Main(string[] args)

{

Application app = new Application();

app.Run(new MyWindow());

}

public MyWindow()

{

Title = "Grid SrcollBar";

Width = 500;

Height = 300;

// SizeToContent = SizeToContent.WidthAndHeight;

Grid maingrid = new Grid();

Content = maingrid;

ColumnDefinition column = new ColumnDefinition();

column.Width = new GridLength(200, GridUnitType.Pixel);

maingrid.ColumnDefinitions.Add(column);

column = new ColumnDefinition();

column.Width = GridLength.Auto;

maingrid.ColumnDefinitions.Add(column);

column = new ColumnDefinition();

column.Width = new GridLength(100, GridUnitType.Star);

maingrid.ColumnDefinitions.Add(column);

Grid grid = new Grid();

maingrid.Children.Add(grid);

Grid.SetRow(grid, 0);

Grid.SetColumn(grid, 0);

grid.ShowGridLines = true;

GridSplitter splitter = new GridSplitter();

splitter.HorizontalAlignment = HorizontalAlignment.Center;

splitter.VerticalAlignment = VerticalAlignment.Stretch;

splitter.Width = 6;

maingrid.Children.Add(splitter);

Grid.SetRow(splitter, 0);

Grid.SetColumn(splitter, 1);

pancel = new StackPanel();

pancel.Background = new SolidColorBrush(SystemColors.WindowColor);

maingrid.Children.Add(pancel);

Grid.SetRow(pancel, 0);

Grid.SetColumn(pancel, 2);

for(int i=0;i<3;i++)

{

RowDefinition trow = new RowDefinition();

ColumnDefinition tcolmn = new ColumnDefinition();

if (i == 1)

trow.Height = new GridLength(100, GridUnitType.Star);//当我错把i==1写成了i==2滚动条一直显示不出来?

else

trow.Height = GridLength.Auto;

tcolmn.Width = new GridLength(33, GridUnitType.Star);

grid.RowDefinitions.Add(trow);

grid.ColumnDefinitions.Add(tcolmn);

}

for (int i = 0; i <3;i++ )

{

Label lbl = new Label();

lbl.Content =( new String[] { "Red","Green","Blue"})[i];

lbl.HorizontalAlignment = HorizontalAlignment.Center;

grid.Children.Add(lbl);

Grid.SetRow(lbl, 0);

Grid.SetColumn(lbl, i);

scrolls[i] = new ScrollBar();

scrolls[i].Focusable = true;

scrolls[i].Orientation = Orientation.Vertical;

scrolls[i].Minimum = 0;

scrolls[i].Maximum = 255;

scrolls[i].SmallChange = 1;

scrolls[i].LargeChange = 10;

scrolls[i].ValueChanged += new RoutedPropertyChangedEventHandler<double>(MyWindow_ValueChanged);

grid.Children.Add(scrolls[i]);

Grid.SetRow(scrolls[i], 1);

Grid.SetColumn(scrolls[i], i);

TextBlocks[i] = new TextBlock();

TextBlocks[i].TextAlignment = TextAlignment.Center;

TextBlocks[i].HorizontalAlignment = HorizontalAlignment.Center;

TextBlocks[i].Margin = new Thickness(5);

grid.Children.Add(TextBlocks[i]);

Grid.SetRow(TextBlocks[i], 2);

Grid.SetColumn(TextBlocks[i], i);

}

Color clr = (pancel.Background as SolidColorBrush).Color;

scrolls[0].Value = clr.R;

scrolls[1].Value = clr.G;

scrolls[2].Value = clr.B;

scrolls[0].Focus();

}

void MyWindow_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)

{

ScrollBar scroll = sender as ScrollBar;

Panel penl = scroll.Parent as Panel;

TextBlock txt = penl.Children[1 + penl.Children.IndexOf(scroll)] as TextBlock;

txt.Text = String.Format("{0}\n0x{0:x2}", (int)scroll.Value);

pancel.Background = new SolidColorBrush(

Color.FromRgb((byte)scrolls[0].Value, (byte)scrolls[1].Value, (byte)scrolls[2].Value));

}

}

一个简单的颜色生成器。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: