Simple Question on control and related Styles

Aug 22, 2013 at 9:59 PM
In the Geek-Control-Textbox.xaml file there is a Style with a targetType = Textbox. This makes sense.

but I don't see a key or name referenced.

If I want to add a style in my projects Theme folder and base it on this style, what do I use for the BaseOn reference?

I am under the impression that if I define a style in my project, that style will override the parent style unless I use BasedOn.

Say I wanted a padding of 3 and to change the BackColor?

On a similar note - in one of your articles on styles, you mentioned an action that would allow me to have an edit mode option - but I didn't see a link. If you happen to have a link to an example, that would be great as most my data can be viewed, but only a few may edit it.

Thanks,
Developer
Aug 23, 2013 at 1:51 PM
Hello Fletcher,
When you see a style without a key name this means it will apply to all controls with that target type. So in this case the all TextBoxes are styled, without having to reference the style name, sort of a global style base.

You are correct in that if you define the same style name in your project it will override the CODE Framework styles compiled in the dll. So if this style had a key/name you could create one with the same key/name in the correct theme folder (making sure the resource file is loaded by the theme file) and it will be used.

Since this particular one has no key/name you would need to create a new style in your project targeting TextBoxes, then add/override properties as desired.

On the "edit mode" note - I'm not sure exactly where or in what context Markus was speaking, but edit modes are generally accomplished by creating a Visiblility property on the view model (like EditModeVisible) and binding to the visibility property of controls. Additionally you create a ReadOnlyVisible property that is the reverse for the non-editable display controls. Simply create an action to trigger the change.
<Grid Background="{Binding OrderBackgroundBrush}">
      <TextBlock Text="{Binding Driver}" Visibility="{Binding ReadOnlyModeVisiblity}"/>
      <ComboBox ItemsSource="{Binding Drivers}"
                         DisplayMemberPath="FullName"
                         SelectedValuePath="FullName"
                         SelectedValue="{Binding Driver}" 
                         Visibility="{Binding EditModeVisiblity}"/>
</Grid>
public bool InEditMode
{
    get { return _inEditMode; }
    set
    {
        _inEditMode = value;
        NotifyChanged("InEditMode"); 
        NotifyChanged("EditModeVisiblity");
        NotifyChanged("ReadOnlyModeVisiblity");
    }
}
public Visibility EditModeVisiblity
{
    get { return InEditMode ? Visibility.Visible : Visibility.Collapsed; }
}
public Visibility ReadOnlyModeVisiblity
{
    get { return !InEditMode ? Visibility.Visible : Visibility.Collapsed; }
}
Jeff
Aug 23, 2013 at 7:39 PM
Jeff,

Thanks, just a quick clarification.
Since this particular one has no key/name you would need to create a new style in your project targeting TextBoxes, then add/override properties as desired. <<
When I create a style with no name or key, but a targetType = Textbox, it appears that this new style overrides any previous definition and my textboxes look considerably different, even if I only change the font color.

When I used the following (just in the edit.xaml while testing):
<Style BasedOn="{StaticResource {x:Type Label}}"
    TargetType="Label"
    x:Key="labelRequiredStyle">

    <Setter Property="Foreground"
        Value="Red" />
</Style>
and then the following label:
<Label Content="Cit No:"
    Style="{StaticResource labelRequiredStyle}" />
When I run the form, both labels that use the above approach are red (good), but are also indented and lower (in terms of layout compared to other label/textbox combinations). I even tried removing the BasedOn="{StaticResource {x:Type Label}}" to see if maybe that was the culprit.

My guess is that I have a simple key word/phrase that I am missing, but not sure what it is. Or could it be because I put the style in the edit.xaml instead of a resource directory?

And, now that you mention binding to a property that indicates if we are in edit mode or not, it's glaringly obvious.... Just keep getting stuck in the old winforms way of doing things (onclick, cycle through all the objects and change their enabled to true, etc.) In essence, it's the same thing, but now relying on NotifyChanged to do that work...

Thanks!
Developer
Aug 24, 2013 at 6:47 PM
Hello Fletcher,
Looking a little further, it appears that all themes other than Geek and Battleship do have a key name for the TextBox style. This may be an oversight in the creation of these themes. As you pointed out this means you can't use the BasedOn to override the style. In these cases you would need to copy the entire style and add/modify to suite your project. So in the example of the Geek TextBox it would be:
    <Style TargetType="TextBox" >
        <Setter Property="FontFamily" Value="{DynamicResource DefaultFont}" />
        <Setter Property="FontSize" Value="{DynamicResource FontSize-Normal}" />
        <Setter Property="Padding" Value="2"/>
        <Setter Property="Background" Value="Lavender" />
    </Style>
Where the first three come from the style as defined in the Geek theme, and the last one is the new property to adjust.

Jeff
Aug 25, 2013 at 6:12 AM
Jeff,

Can you check with Markus to see if the Key will be added to those two themes? If so, then I will update my copy of the FW to include a Key appropriate for those themes given the Key used in the other themes. Then my styles in the application Theme files will be more consistent as well as able to inherit any other changes that may be introduced to the default themes in a later build.

If not, then I will do as you say by copying the full style info into my application themes.

Also, I have had to create a couple of generic type converters for some of my bindings. I found a few in the FW, but was wondering if there were any docs on those or if they are there primarily for internal FW use (which is what appears to be the case on a casual review.) If the converters I create are generic enough and can be used, where would be a good place for me to upload so others can use them if they wish?

Thanks!

Fletcher
Aug 26, 2013 at 11:30 PM
Jeff,

Ok, having gone through and added the key values to the obvious styles that were missing it (and created a new discussion on that topic), I still had the problem. Thanks to the Document Visualizer, I was able to track down the culprit. The CODE.Framework-Layout-EditFormLayout in the Geek file has the following:
<Style TargetType="ItemsControl" x:Key="CODE.Framework-Layout-EditFormLayout">
    <Setter Property="Background" Value="{DynamicResource CODE.Framework-Application-BackgroundBrush4}"/>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <layout:EditForm Margin="10" LayoutElasticity="LayoutAndReflow" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Style.Resources>
        <Style TargetType="Label">
            <Setter Property="Foreground" Value="{DynamicResource CODE.Framework-Application-ForegroundBrush4}" />
            <Setter Property="FontSize" Value="{DynamicResource FontSize-Normal}"/>
            <Setter Property="FontFamily" Value="{DynamicResource DefaultFont}"/>
            <Setter Property="Margin" Value="0" />
            <Setter Property="Padding" Value="0" />
        </Style>
    </Style.Resources>
</Style>
In the 2nd section, a Label is defined. It's not based on the current label, nor is it given a key value. But this is the label that is used by the form (the Margin and Padding both being set to 0 helped me track it down.)

I will play with it, but I assume I have to give this label a key and then use that for a BasedOn value. Or I just copy the Setters to the style I am creating (although I am sure that the CODE FW will eventually include a few move values - which might get overlooked.

Thanks,

Fletcher
Aug 27, 2013 at 1:21 AM
Jim,

So what I have (which seems to work just fine) is the following:
<Style TargetType="Label"
    x:Key="CODE.Framework-Layout-EditFormLayout-Label">
    <Setter Property="Foreground"
        Value="{DynamicResource CODE.Framework-Application-ForegroundBrush4}" />
    <Setter Property="FontSize"
        Value="{DynamicResource FontSize-Normal}" />
    <Setter Property="FontFamily"
        Value="{DynamicResource DefaultFont}" />
    <Setter Property="Margin"
        Value="0" />
    <Setter Property="Padding"
        Value="0" />
</Style>

<Style TargetType="ItemsControl"
    x:Key="CODE.Framework-Layout-EditFormLayout">
    <Setter Property="Background"
        Value="{DynamicResource CODE.Framework-Application-BackgroundBrush4}" />
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <layout:EditForm Margin="10"
                    LayoutElasticity="LayoutAndReflow" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Style.Resources>
        <Style TargetType="Label"
            BasedOn="{StaticResource CODE.Framework-Layout-EditFormLayout-Label}">
        </Style>
    </Style.Resources>
</Style>
I could then use the label style in the edit form and it matched the other labels in the edit form.

Is there anything wrong with this approach (other than that I edited the FW xaml)? And what are the chances that this will end up in the next version (or should I just copy this down to my application them folders/files)?

Thanks,

Fletcher
Coordinator
Sep 4, 2013 at 10:59 PM
To add my 2 cents here: We usually have a named style and an implicit style that derives from it (is "based on it"). In the case of the geek textbox, we haven't done that yet, mainly because the style is so simple and just sets fonts and some extra padding. We could still create a named style for that, but I would think that the overhead just isn't worth it. So if you were to create a new style, I would just suggest you copy those settings over.

I have however taken a note to see if there are any places where we should add the named styles.

BTW: You can also base your style not only on a named style, but you can base your new style on the implicit default for a certain type. The syntax would then look like this:
BasedOn="{StaticResource {x:Type TextBox}}"
Markus