Control Templates « Dr. WPFAs we continue our series on Items. Control, it probably makes sense to take a small detour and look at WPF controls in general. In this post, we will examine how WPF controls get their visual representation through styles and templates. Then we will look at how these techniques specifically apply to several Items. Control classes. This article is fairly long and covers a lot of really important information, including the following: It is definitely worth taking your time to understand these concepts. Feel free to break the article up into more manageable pieces if you are time- constrained. MSDN Magazine Issues and Downloads. Read the magazine online, download a formatted digital version of each issue, or grab sample code and apps.I would also encourage you to keep kaxaml up and running as you learn about styles and templates. I think you’ll find that it makes the content more meaningful when you directly interact with the samples. As such, this article contains a lot of kaxamples, which is my term for kaxaml- ready samples. When you see the kaxaml symbol, you know you can cut and paste the included markup snippet directly into kaxaml to interact with it live. Then you are free to tweak the markup and make a few cool new styles and templates of your own! The Lookless Control Model. When developers first start learning WPF, they are often very surprised to learn that a WPF control does not include a hardcoded visual representation. Rather, the default visual representation is specified in XAML in a completely separate theme assembly from the class that implements the control’s logic. This separation of code- based logic from visual representation (the control’s look and feel) is what makes the WPF control model so powerful. We refer to this approach as a “lookless control model”. Why, you may be asking, is such a model better than the traditional approach of defining the visuals as part of the control? I’ll give you two big reasons: design and reusability. If you’ve studied WPF or Silverlight much, you have certainly heard about the new developer/designer workflow that these technologies enable. ![]() I have a GridView which you can click on a row and it should call the SelectedIndexChanged method (which updates another part of the page based on which row was. PowerShell (including Windows PowerShell and PowerShell Core) is a task automation and configuration management framework from Microsoft, consisting of a command-line. Namely, developers and designers can work side by side to simultaneously create powerful and visually stunning applications, with each person doing what they do best. A developer can implement an application’s logic at the same time that a designer creates the application’s look and feel. To a great degree, it is the lookless control model that enables this new workflow. It turns out that left- brained developers don’t always come up with the most eye- pleasing visual designs, as can be seen by looking at the “battleship gray” user interfaces coming out of the Windows Forms world for the past decade. Now contrast these apps with the vibrant Flash- based web applications created in the same timeframe. The big difference is that most of the cool Flash applications were created by right- brained designers who take aesthetics very seriously. Yes, I’m stereotyping with the whole left- brained/right- brained thing… some stereotypes are just true.)By introducing a lookless control model where the visual representation of the control is specified apart from the control’s code, we are able to put the visual design into the hands of a qualified UX designer, where it belongs. The second big reason for separating a control’s visuals from its code implementation is reusability. In the past, if you wanted to have two buttons with different visual appearances, you had to create two separate button classes with the correct rendering code baked into each class. Both classes contained the same basic button logic. They both provided a “click” event in response to the appropriate mouse or keyboard user interactions. The only difference between the button classes was in the rendering logic. By moving the visual representation into XAML and out of the control class, we allow a single Button class to be reused wherever we need to support a Click interaction. ![]() The button can have whatever visual representation the designer wants to create. The developer no longer needs to be involved in the process of redefining a button’s visual representation. An example of this reusability can be seen in the following image (borrowed from my Observable Dictionary Sample) depicting a List. View in which each row contains a style name and a button. The only difference between each button is the “Style” used to define the button’s look and feel. Introduction to Styles. We have already seen an example of how one might style and template an item container via the Item. ![]() Container. Style property (see ‘I’ is for Item Container). Now it’s time to actually dig into the nitty gritty details of control styling and templating. If you are already familiar with styling and templating, you can skip ahead to the section entitled Templating an Items Control. Of course, you might consider continuing on through the following sections as a refresher course and it’s possible you might even learn something new. P)A WPF style consists of a collection of property values that are applied to a framework element either explicitly (by setting its Style property) or implicitly (based on a resource lookup using the element’s default style key). These property values are applied using Setter objects. Thus, a style can be thought of as a collection of Setter objects. Here is a very simple example: < Style. Target. Type="{x: Type. Rectangle}">. < Setter. Property="Width" Value="5. Setter. Property="Height" Value="5. Style> In this case, a style is created for a Rectangle. There are two setters in the style. These set the Width and Height properties of the Rectangle to 5. So how do you actually use the style? Typically, you will give it a resource key and add it to a resource dictionary somewhere in your element hierarchy. Then you can use the resource key to apply the style to specific elements in the subtree. Here is a kaxample: < Gridxmlns="http: //schemas. Grid. Resources>. Stylex: Key="My. Rectangle. Style". Target. Type="{x: Type. Rectangle}">. < Setter. Property="Width" Value="5. Setter. Property="Height" Value="5. Style>. < /Grid. Resources>. < Stack. Panel. Orientation="Horizontal">. Rectangle. Style="{Static. Resource. My. Rectangle. Style}" Fill="Red" />. Rectangle. Style="{Static. Resource. My. Rectangle. Style}" Fill="Green" />. Rectangle. Style="{Static. Resource. My. Rectangle. Style}" Fill="Blue" />. Rectangle. Style="{Static. Resource. My. Rectangle. Style}" Fill="Black" />. Stack. Panel>. < /Grid> In the above example, the style is explicitly applied to each Rectangle because we have set the Style property on the Rectangle elements. If we want the style to be applied implicitly to every Rectangle in the subtree, we can simply remove the x: Key attribute from the style declaration and then not specify the Style property on the Rectangle elements, as shown in this kaxample: < Gridxmlns="http: //schemas. Grid. Resources>. Style. Target. Type="{x: Type. Rectangle}">. < Setter. Property="Width" Value="5. Setter. Property="Height" Value="5. Style>. < /Grid. Resources>. < Stack. Panel. Orientation="Horizontal">. Rectangle. Fill="Red" />. Rectangle. Fill="Green" />. Rectangle. Fill="Blue" />. Rectangle. Fill="Black" />. Stack. Panel>. < /Grid> You may be curious as to why the above style is applied to all Rectangle elements in the subtree. The answer is hidden in the framework’s parsing routine for resource dictionaries. Each element added to a resource dictionary must have a key. It is noteworthy that the style above is conspicuously missing an x: Key attribute. It turns out that the XAML parser has special handling for Style objects that are added to a resource dictionary. If no key is specified, the parser uses the style’s Target. Type as its key. So the above style declaration is actually equivalent to the following: < Stylex: Key="{x: Type. Rectangle}" Target. Type="{x: Type. Rectangle}">. Setter. Property="Width" Value="5. Setter. Property="Height" Value="5. Style> There is a convention in WPF that an element’s type is used as its default style key. As mentioned earlier, if the Style property is not explicitly set on a framework element, a resource lookup takes place using this default style key (the element type) to find an appropriate style. Hence, in the example above, our style is applied to each Rectangle as a result of its default style key. Now let’s take a look at a styling feature that even some of the most experienced designers may not know about…Our style above can only be applied to Rectangle elements. Why doesn't my Grid. View Selected. Index. Changed event fire? I have a Grid. View which you can click on a row and it should call the Selected. Index. Changed method (which updates another part of the page based on which row was selected). I have done something similar to this before and it worked, but I can't seem to get the Selected. Index. Changed part to be called for some reason. The page is held in a master page which has a form runat="server" tag, and an < asp: Script. Manager> tag. I am using e. Row. Attributes. Add("onclick", Client. Script. Get. Post. Back. Client. Hyperlink(Me. Messages, "Select$" & e. Row. Row. Index)) to allow the Selected. Index. Changed to fire by clicking anywhere on the row. To check that the code does work apart from that, I added a Command. Field with a Select. Button and that successfully fires, but i would prefer to find a solution without having to use that. Thanks. Grid. View: < asp: Update. Panel ID="Update. Panel. 1" runat="server" Update. Mode="Always">. Content. Template>. Hidden. Field runat="server" ID="hdn. Scroll. Position" />. Grid. View ID="grid. Messages" runat="server" Css. Class="grid. View" Auto. Generate. Columns="False". Allow. Paging="true" Grid. Lines="None" Page. Size="1. 0" Show. Header="True". Empty. Data. Text="- -No Messages Received- -" Width="1. Columns>. < asp: Template. Field Header. Text="Messages Received" Header. Style- Horizontal. Align="Left" Header. Style- Css. Class="header. Class">. < Item. Template>. ... < /Item. Template>. < /asp: Template. Field>. < /Columns>. Grid. View>. < /Content. Template>. < /asp: Update. Panel>. Code- Behind: Protected Sub Page_Load(By. Val sender As Object, By. Val e As System. Event. Args) Handles Me. Load. If Not Is. Post. Back Then. Me. grid. Messages. Data. Source = .. Me. grid. Messages. Data. Bind(). Protected Sub grid. Messages_Row. Data. Bound(By. Val sender As Object, By. Val e As System. Web. UI. Web. Controls. Grid. View. Row. Event. Args) Handles grid. Messages. Row. Data. Bound. If e. Row. Row. Type = Data. Control. Row. Type. Data. Row Then. e. Row. Attributes. Add("onmouseover", "this. Color='#D2. E6. F8'"). Row. Attributes. Add("onmouseout", "this. Color='#ffffff'"). Row. Attributes. Add("onclick", "save. Scroll. Position(); " & Client. Script. Get. Post. Back. Client. Hyperlink(Me. Messages, "Select$" & e. Row. Row. Index)). Selected. Index. Changed (which never fires): Protected Sub grid. Messages_Selected. Index. Changed(By. Val sender As Object, By. Val e As System. Event. Args) Handles grid. Messages. Selected. Index. Changed. Response. Redirect("test. aspx").
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. Archives
November 2017
Categories |