tags:

views:

258

answers:

4

In my LOB apps I usually wind up with containers that contain a bunch of different textblocks and textboxes for users to enter data. Normally I need to apply a certain margin or vertical/horizontal alignment to each control.

Let's say I have Grid on my form that looks like this (a lot of markup was eliminated for brevity):

<Grid>
   <Grid.ColumnDefinitions.../>
   <Grid.RowDefinitions.../>

   <TextBlock Text="MyLabel" />
   <TextBox Text={Binding ...}/>
   .
   '
   <!-- Repated a bunch more times along with all of the Grid.Row, Grid.Column definitions -->
</Grid>

Now let's say I need every single item contained in my grid to have Margin="3,1" VerticalContentAlignment="Left" VerticalAlignment="Center". There are several ways to achieve this:

  1. Set the properties directly on each control - BAD!! Does not allow for skinning or centralizing styles.
  2. Create a Style with an x:Key="MyStyleName" and apply the style to each control. Better...Makes centralizing styles and skinning more manageable but still requires a ton of markup, and can become unwieldy.
  3. Create a global style (i.e. don't specify an x:Key and set the TargetType={x:Type TextBox/TextBlock} - BAD!! The problem with this is that it affects ALL controls in the app that don't explicity override this style. This can be bad for things like menus, grids, and other controls that use textblocks and textboxes.
  4. Create a style that targets the Grid and explicitely sets the dependecy propety values like <Setter Property="Frameworkelement.Margin" Value="3,1" /> Not bad...it correctly applies the style to every element in it's content, but also applies it directly to the Grid itself...not exactly what I want.

So what approach do you take and why? What works the best?

A: 

You could use #4 but then explicitly override those properties on the Grid itself.

thealliedhacker
A: 

Check this out.

http://karlshifflett.wordpress.com/2008/10/23/wpf-silverlight-lob-form-layout-searching-for-a-better-solution/

I find them a great help for LOB apps. The source is available so even if you don't use the library, you can get an idea of how to do global styling.

Jab
I use to work with Karl. I discussed that solution with him, but even he said he would probably do it differently.
Micah
+3  A: 

You can put a "global" style into the Resources section of the grid, thus confining its impact. To re-use "global" styles in different locations, put them into a non-default resource dictionary and include it as MergedDictionary:

in Styles.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <Style x:Key="{x:Type ...}"> ... </Style>
</ResourceDictionary>

in the form:

<Grid>
   <Grid.ColumnDefinitions.../>
   <Grid.RowDefinitions.../>

    <Grid.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>

            <!-- other resources here -->

        </ResourceDictionary>
    </Grid.Resources>

    ...
</Grid>
David Schmitt
A: 

Here is a solution that I came up with using an Attached Property:

Coding Context Article

Micah