1. Trang chủ
  2. » Công Nghệ Thông Tin

Programming C# 4.0 phần 10 pdf

93 303 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 93
Dung lượng 10,42 MB

Nội dung

Content="Row 1, 3 columns wide" /> <Button Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3" Content="Row 2, 3 columns wide" /> <Button Grid.Column="1" Grid.Row="3" FontSize="50" Content="(3, 1)" /> </Grid> Figure 20-2 shows how this looks. The four rows are fairly clear—each button belongs to just one row. The columns are less obvious—you can see all three clearly in the first row, because there’s one button in each, but the next two rows contain just one button each, spanning all three rows. And the final row contains a single button in the second column. Figure 20-2. Grid children The Grid knows which columns and rows elements belong to, and how many they span, because each button in Example 20-4 has properties that control this. The Grid.Column and Grid.Row properties do what their names suggest, while the Grid.ColumnSpan and Grid.RowSpan properties determine how many grid cells the ele- ment occupies. The column and row default to 0, while the spans default to 1. 740 | Chapter 20: WPF and Silverlight These properties use another special Xaml feature called attached prop- erties. An attached property is one defined by a different type (e.g., Grid) than the object it is applied to (e.g., Button). The attached prop- erties in Example 20-4 are attributes, but you can also set attached properties with the property element syntax shown earlier—for example, if a <Grid> element could contain a <ToolTipService.Tool Tip> element, to set the attachable ToolTip property defined by the ToolTipService class. While Silverlight, WPF, and Xaml support the idea that properties don’t necessarily have to be defined by the object on which they are set, C# has no syntax for this. So classes that define attachable properties also define get and set methods to enable those properties to be used from code. For example, the Grid class offers SetColumn, SetRow, and so on. The rows and columns in Figure 20-2 are different sizes. This is because of the settings on the <RowDefinition> and <ColumnDefinition> elements. The first column’s Width has been set to Auto, so it takes its size from the widest child in that column. In this case, only one child belongs exclusively to that column, so the column is exactly wide enough to hold it. The other two columns are at their default width, the value 1*, which causes them to share the remaining space equally. The rows use similar features, except the first row has a fixed height of 30, so it ignores the size of the content and makes every element 30 pixels high. The final row is Auto sized, and since its content has a large font size, it ends up being fairly tall. And the middle two rows use so-called star sizing, so as with the second and third columns, they end up sharing the space left over. However, since they have different star size values—1* and 2*—they get different amounts of space. The 2* row gets to be twice the height of the 1* row. Note that the ratios are all that matter with star sizing—changing 1* and 2* to 10* and 20* would not change the outcome in this example, because 20* is still twice as large as 10*. So as you can see, a grid can use fixed sizes, it can base sizes on the content at hand, or it can divide the available space proportionally. This makes it a pretty flexible layout mechanism. You can build dock-style layouts where elements are aligned to the top, bottom, left, or right of the available space through the use of Auto sized rows and columns, and by making elements span all the available rows when docking to the left or right, or all the columns when docking to the top or the bottom. You can also stack elements horizontally or vertically by using multiple rows or columns with Auto sizes. And as we’ll see, it’s even possible to exercise precise control over the size and position of elements within the grid. One slight problem is that your Xaml can get a little verbose when using grids. So there are some simpler panel types. StackPanel arranges children in a vertical or horizontal stack. Example 20-5 shows a StackPanel with its Orientation set explicitly to Vertical. You can doubtless guess how to make a horizontal stack. (In fact, vertical stacks are the default, so you could leave the orientation out from Example 20-5 without changing its behavior.) Elements and Controls | 741 Example 20-5. Vertical StackPanel <StackPanel Orientation="Vertical"> <Button Content="Buttons" FontSize="30" /> <Button Content="in" /> <Button Content="a" /> <Button Content="stack" /> </StackPanel> Figure 20-3 shows the result. Notice that in the direction of stacking—vertical in this example—the behavior is similar to the Auto height grid rows, in that each row has been made tall enough to accommodate the content. In the other direction, the elements have been stretched to fill the available space, although as we’ll see shortly, you can change that. Figure 20-3. Vertical StackPanel The Canvas panel takes an even simpler approach: it doesn’t have a layout strategy, and it simply puts elements where you tell it to. As Example 20-6 shows, just as Grid offers attachable properties to specify which grid cells elements occupy, Canvas defines at- tachable Left and Top properties that specify where the elements should appear. Example 20-6. Explicit positioning with Canvas <Canvas> <Button Content="Buttons" FontSize="30" /> <Button Canvas.Left="20" Canvas.Top="40" Content="on" /> <Button Canvas.Left="80" Canvas.Top="40" Content="a" /> <Button Canvas.Left="60" Canvas.Top="100" Content="Canvas" /> </Canvas> As Figure 20-4 shows, the exact positioning possible with a Canvas has let us position elements so that they overlap. (This figure includes some of the browser chrome to illustrate that positions are relative to the top-left corner of the Canvas.) Notice that the Canvas sizes children based on how much space they require—similar to the Auto rows and columns, but in this case the buttons are sized to content in both dimensions. Unless you specify explicit widths and heights, a Canvas will attempt to give each child exactly as much space as it requires. 742 | Chapter 20: WPF and Silverlight Silverlight and WPF have extensible layout systems, so you can derive your own types from Panel or use libraries that offer other panels. For example, Microsoft offers the Silverlight Toolkit, a free library you can download in source or binary form from http: //silverlight.codeplex.com/, which defines various controls, panels, and other useful components. This includes two panels, both based on panels that are built into WPF. There’s WrapPanel, which lays out its children in much the same way that text is word- wrapped in web browsers and word processors—items are arranged from left to right until all the space is used up, at which point the panel starts on a new line. And there’s also DockPanel, which lets you arrange elements by stacking them up against the left, right, top, or bottom of the panel. (DockPanel doesn’t do anything Grid can’t do, but it can be slightly simpler to use.) Layout in WPF and Silverlight is not just about panels. Panels define the strategy by which elements are allocated a layout slot—the area on-screen in which they must fit themselves. But properties are available on all elements—regardless of the panel in use—that can influence both how big the layout slot is and what the element does with the space it is offered. General-purpose layout properties All elements have common properties that influence layout. There are Width and Height properties that let you specify an explicit size, rather than basing the size on the content or the available space. This is important for elements that don’t otherwise have an intrinsic size. Textual content has a natural size, but some graphical elements such as Ellipse and Rectangle don’t. If you were to create an Ellipse without setting the height and put it in a vertical StackPanel it would vanish, because the StackPanel asks it to calculate the minimum amount of space it requires, and if you have not specified any constraints, that’ll be zero. So elements with no intrinsic size usually have an ex- plicit Width and Height, or you might use MinWidth and MinHeight to ensure that they never vanish entirely, but are able to expand to fill whatever space is available—some layouts will end up with more space than needed if the user resizes a window, so it can be useful to have a layout that adapts. MaxWidth and MaxHeight let you specify upper limits on just how far elements will expand. Figure 20-4. Buttons on a Canvas Elements and Controls | 743 The various width and height properties are useful when an element is being asked to determine its own size, such as in Auto sized grid cells. But sometimes an element’s layout slot size is imposed on it—for example, if your Silverlight user interface is con- figured to fill the entire browser window, the user is in charge of how big it is. This is sometimes referred to as constrained layout—this describes situations where the layout system has to make things fit a predetermined space, rather than trying to work out how much space is required. Most user interfaces contain a mixture of constrained and unconstrained layout—the top level of the UI is usually constrained by window size, but you might have individual elements such as text blocks or buttons that have to be large enough to display their content. When elements that have no intrinsic size are put in a constrained lay- out, they will fill the space available if you don’t set the width and height. For example, if you put an Ellipse as the only element of the root Grid layout element, and you don’t set any of the width or height prop- erties, it will fill the whole Silverlight application UI. You can even get a mixture of constrained and unconstrained layouts on one element. In Figure 20-3, we saw a vertical stack of elements, and vertically, each one’s size was based on its content—since the elements are free to size themselves it means we have unconstrained layout vertically. But the elements are all the same width regardless of content, indicating that constrained layout was in use horizontally. Stack panels always work this way—children are unconstrained in the direction of stacking, but are con- strained to have the same sized layout slots in the other direction. When an element has more space than it needs due to constrained layout, additional properties that determine what the element does with the excess space come into play. The HorizontalAlignment attribute lets you position the element within its slot. Exam- ple 20-7 shows a modified version of Example 20-5, specifying each of the four HorizontalAlignment options. Example 20-7. Horizontal alignment <StackPanel Orientation="Vertical"> <Button Content="Buttons" FontSize="30" HorizontalAlignment="Left" /> <Button Content="in" HorizontalAlignment="Right" /> <Button Content="a" HorizontalAlignment="Stretch" /> <Button Content="stack" HorizontalAlignment="Center" /> </StackPanel> 744 | Chapter 20: WPF and Silverlight Figure 20-5 shows the results. As before, each child has been given a layout slot that fills the whole width of the StackPanel, but all except the third row have been sized to content, and have then positioned themselves within their slot based on the HorizontalAlignment property. The third button still fills the whole of its row because its alignment is Stretch. That’s the default, which is why elements fill their whole layout slot unless you specify an alignment. VerticalAlignment works in much the same way, offering Top, Bottom, Center, and Stretch. Figure 20-5. Horizontal alignment The alignment properties do something only when the layout slot is larger than the element requires. When an element has been given a slot exactly as large as it asked for in either the horizontal or vertical dimen- sion, the corresponding alignment property does nothing. So setting VerticalAlignment on the child of a vertical StackPanel does nothing— the layout slot is already exactly as tall as the element requires, so the element is simultaneously at the top, the bottom, and the center of the slot. Another very important ubiquitous layout property is Margin—this lets you specify the amount of space you’d like between the edge of an element and the boundary of its layout slot. In unconstrained layout, a margin will cause an element to be given a larger slot than it would otherwise have had, while in constrained layout, it causes an element to fill less of the slot than it otherwise would have. Example 20-8 illustrates this within a vertical StackPanel—since this uses constrained horizontal layout and unconstrained vertical layout for its children, we’ll see both effects. Example 20-8. Buttons with Margin properties <StackPanel Orientation="Vertical"> <Button Content="Buttons" FontSize="30" /> <Button Content="in" Margin="10" /> <Button Content="a" Margin="20" /> <Button Content="stack" Margin="30" /> </StackPanel> Elements and Controls | 745 In Figure 20-6, the first button fills the entire width because it has no margin. But each successive button gets narrower, because each has a larger margin than the last. Since the width is constrained, the layout system needs to make the buttons narrower to provide the specified margin between the element’s edges and its layout slot. But since the children here are unconstrained vertically, the margin has no effect on their vertical size, and instead ends up adding increasing amounts of space between each element— in the unconstrained case, Margin makes the slot larger. Figure 20-6. Buttons with margins Example 20-8 specifies the margins as single numbers, denoting a uniform margin on all four sides, but you can be more precise. You can provide two numbers, setting the horizontal and vertical margins. Or you can provide four numbers, indicating the left, top, right, and bottom ‡ margins independently. This enables precise positioning of elements within a Grid—it turns out that you don’t have to use a Canvas to specify the position of an element. If you align an element to the left and the top, the first two numbers in a margin effectively determine its position within the containing grid cell, just as the attachable Canvas.Left and Canvas.Top properties work for children of a Canvas. The interactive design surfaces in Visual Studio and Blend use this to let you drag elements around on a grid and place them exactly where you want. It appears to be a completely free form of layout, but if you inspect what these programs do to the Xaml as you move elements around, they simply set the alignment properties appro- priately and adjust the margins. All of the layout features we’ve looked at so far take a rigidly rectangular approach— everything is either strictly horizontal or strictly vertical. In fact, WPF and Silverlight are a bit more flexible than that, thanks to their support for transforms. ‡ Yes, that is a different order than CSS. Silverlight and WPF follow the coordinate geometry convention of specifying pairs of coordinates as horizontal and then vertical measures—x before y. Hence left, then top, followed likewise by right, then bottom. 746 | Chapter 20: WPF and Silverlight Transforms You can apply a transform to any element, modifying its size, position, and orientation, or even skewing it. (If you’re familiar with the coordinate geometry features found in most modern graphics system, you’ll recognize these as being the usual two- dimensional affine transformations possible with a 2×3 matrix. § ) Example 20-9 shows another variation on our StackPanel example, with transforms applied to the children. Example 20-9. Transforms <StackPanel Orientation="Vertical"> <Button Content="Buttons" FontSize="30"> <Button.RenderTransform> <ScaleTransform ScaleX="1.5" ScaleY="0.5" /> </Button.RenderTransform> </Button> <Button Content="in"> <Button.RenderTransform> <RotateTransform Angle="30" /> </Button.RenderTransform> </Button> <Button Content="a"> <Button.RenderTransform> <SkewTransform AngleX="30" /> </Button.RenderTransform> </Button> <Button Content="stack"> <Button.RenderTransform> <TranslateTransform Y="-50" /> </Button.RenderTransform> </Button> </StackPanel> As Figure 20-7 shows, the RenderTransform property Example 20-9 uses can mess up the layout. The transform is applied after the layout calculations are complete, so the ScaleTransform on the first button has had the effect of making it too large to fit—the default HorizontalAlignment of Stretch is in effect here, so the button has been made exactly as wide as the containing StackPanel, and then has been scaled to be 1.5 times wider and 0.5 times higher, causing it to be cropped horizontally. Likewise, the ele- ments that have been rotated and skewed have had corners cut off. WPF offers a LayoutTransform property that takes the transform into account before performing lay- out, which can avoid these problems, but Silverlight does not—you would need to tweak the layout to get things to fit. A transform applies not just to the target element, but also to all that element’s children. For example, if you apply a RotateTransform to a panel, the panel’s contents will rotate. § Strictly speaking, it’s a 3×3 matrix, but the final column is fixed to contain (0, 0, 1). Elements and Controls | 747 This support for rotation, scaling, and shearing reveals that WPF and Silverlight are designed to support more graphically interesting user interface styles than traditional, rigidly rectilinear Windows user interfaces. So this seems like a good time to look at some of the graphical elements. Graphical Elements WPF and Silverlight support several kinds of graphical elements. The shape elements provide scalable vector-oriented two-dimensional shapes. There are also various ways to incorporate bitmap images. Video is supported through the media element. And WPF and Silverlight both provide some support for 3D graphics, although they take rather different approaches. Shapes Shape is the base class of various two-dimensional shapes. It’s an abstract class, and it defines common properties such as Fill and Stroke to control how the interior and outline of shapes are painted. Some of the derived classes are self-explanatory—it doesn’t take much imagination to work out what Ellipse, Rectangle, and Line do. Polyline, Polygon, and Path require a little more explanation. Polyline lets you define a shape as a series of straight lines—you simply provide a list of coordinate pairs defining each point the shape’s outline passes through. Polygon does the same thing, but closes off the shape—it automatically joins the final point with the first one. However, you rarely use either of these, because Path lets you do all this and more. (Expression Blend never creates Polyline or Polygon elements—even if you create a shape whose outline is made up entirely of straight edges, it still makes a Path. And most Xaml export tools from programs such as Adobe Illustrator do the same. So in practice, Path is the one you’ll come across. The other two exist because they are slightly simpler to work with from code.) Figure 20-7. Transformed buttons 748 | Chapter 20: WPF and Silverlight Path lets you define a shape with any mixture of straight and curved segments in its outline. Example 20-10 shows a Path made up entirely of straight edges. Example 20-10. Path with straight edges <Path Fill="Red" Stroke="Black" StrokeThickness="5" Data="M50,0 L100,50 50,100 0,50 z" /> The Data property defines the shape. It consists of a series of commands and coordi- nates. The letters indicate the command—the initial M means Move to the specified position, (50, 0) in this case. The L means draw a Line to the next coordinate. And since this example has three coordinate pairs after the L, even though L requires only one, that means we repeat the command—so that’s three straight line segments passing through the coordinates (100, 50), (50, 100), and (0, 50). Each segment starts where the previous one left off. Finally, the z indicates that we’d like to make this a closed shape, so it will join that final point back up with the first one to form the diamond shape you see in Figure 20-8. This shape is filled in and given a thick outline, thanks to the Fill, Stroke, and StrokeThickness properties, which are available on any shape element. The shape defined by the Data describes the center of the line drawn for the outline. This means that making the StrokeThickness larger effec- tively increases the size of the shape—a thicker outline will encroach into the interior of the shape, but will also expand outward by the same amount. That means that the Path in Example 20-10 has a bounding box slightly larger than that implied by the coordinates in the Data. The first line segment starts at (50, 0), which is at the very top of the shape, but the stroke thickness means that the peak of the shape actually ap- pears a bit higher. (The peak is at approximately (50, −3.54). The angle of this particular stroke means that the top corner is above the specified point by half the stroke thickness multiplied by √2.) So if you put this path at the very top left of the UI its top and left corners will be slightly cropped. Figure 20-8. Path with straight edges Elements and Controls | 749 [...]... CHAPTER 21 Programming ASP.NET Applications Developers are writing more and more of their applications to run over the Web and to be seen in a browser As we saw in Chapter 20, Silverlight lets you write C# code to run on the client side in the web browser As for the server side of a web application, the NET Framework offers ASP.NET The focus of this chapter is to illustrate where ASP.NET and C# programming. .. this: This creates a button with a green ellipse as its content Or you can get more ambitious and put a panel in there: ... 20-12 sets the fill of a shape to a radial gradient brush, and sets its stroke to be a linear gradient brush Example 20-12 Gradient brushes for fill and stroke 750 | Chapter 20: WPF and... and a single cubic Bezier curve segment, indicated with the C command Example 20-11 Path with Bezier curve and straight edges Cubic Bezier curves require four points to define them So the C command demands three pairs of coordinates (The first point is wherever the previous command finished, so it... Example 20-17 ListBox with mixed content 756 | Chapter 20: WPF and Silverlight Figure 20-12 shows the results As well as showing... Explicit TreeViewItem containers ... Path (Again, you may find that the image appears only at runtime, not at design time.) Example 20-14 Painting a shape with an ImageBrush You don’t have to download images with HTTP You can... ASP.NET-specific book, we will look only at the simpler, RAD-based Web Forms model Web Forms offers a programming model in which web pages are dynamically generated on a web server for delivery to a browser over the Internet With Web Forms, you can create an ASPX page consisting of HTML and web controls, and you write C# code to 775 ... As you can see in Figure 20 -10, these brushes change color across the shape The radial brush starts from a point in the middle (or some other point—there are properties to control the exact settings) and spreads out to an elliptical... a chapter, but Example 20-15 shows a typical example Elements and Controls | 753 Example 20-15 An animation Animations are separate objects from . StrokeThickness=" 10& quot; Data="M 50, 0 L 100 , 50 C125, 74 75,125 50, 100 L0, 50 z" > <Path.Fill> <RadialGradientBrush> <GradientStop Offset=" ;0& quot; Color="Blue". straight edges. Example 20- 10. Path with straight edges <Path Fill="Red" Stroke="Black" StrokeThickness="5" Data="M 50, 0 L 100 , 50 50, 100 0, 50 z" /> The. command. Example 20- 11. Path with Bezier curve and straight edges <Path Fill="Red" Stroke="Black" StrokeThickness="5" Data="M 50, 0 L 100 , 50 C125, 74 75,125 50, 100 L0, 50 z"

Ngày đăng: 06/08/2014, 09:20

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN