8

I am having a big issue with how XAML is rendered in Design-Time vs Run-Time. For the most part, things are consistent, but when I use any styles which have a Trigger, the trigger is not checked in Design-Time.

Here is a sample application to show how things are displayed differently:

<Window x:Class="DesignDifferencesWithDesignAndRuntime.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="400" Width="400">
<Window.Resources>
    <Style x:Key="multiLineInTrigger" TargetType="{x:Type TextBox}">
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="Width" Value="150" />
        <Setter Property="Height" Value="22" />
        <Setter Property="BorderBrush" Value="Blue" />
        <Setter Property="BorderThickness" Value="2" />
        <Style.Triggers>
            <Trigger Property="AcceptsReturn" Value="True">
                <Setter Property="Width" Value="Auto" />
                <Setter Property="Height" Value="Auto" />
                <Setter Property="HorizontalAlignment" Value="Stretch" />
                <Setter Property="VerticalAlignment" Value="Stretch" />
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="singleLineInTrigger" TargetType="{x:Type TextBox}">
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="Width" Value="Auto" />
        <Setter Property="Height" Value="Auto" />
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
        <Setter Property="BorderBrush" Value="Blue" />
        <Setter Property="BorderThickness" Value="2" />
        <Style.Triggers>
            <Trigger Property="AcceptsReturn" Value="False">
                <Setter Property="Width" Value="150" />
                <Setter Property="Height" Value="22" />
                <Setter Property="HorizontalAlignment" Value="Left" />
                <Setter Property="VerticalAlignment" Value="Center" />
            </Trigger>
        </Style.Triggers>
    </Style>   
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="HorizontalAlignment" Value="Right" />
    </Style>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="150" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <TextBlock Text="Single (Single Style)" Grid.Row="0" Grid.Column="0" />
    <TextBlock Text="Single (Multi Style)" Grid.Row="1" Grid.Column="0" />
    <TextBlock Text="Multi (Single Style)" Grid.Row="2" Grid.Column="0" />
    <TextBlock Text="Multi (Multi Style)" Grid.Row="3" Grid.Column="0" />

    <TextBox Grid.Row="0" Grid.Column="1" Style="{StaticResource singleLineInTrigger}" />
    <TextBox Grid.Row="1" Grid.Column="1" Style="{StaticResource multiLineInTrigger}" />
    <TextBox Grid.Row="2" Grid.Column="1" Style="{StaticResource singleLineInTrigger}" AcceptsReturn="True" />
    <TextBox Grid.Row="3" Grid.Column="1" Style="{StaticResource multiLineInTrigger}" AcceptsReturn="True" />
</Grid>

I created two separate TextBox styles which do the exact same thing. When the TextBox is Single-Line (AcceptsReturn = False) I need the width to be 150, and the height to be 22. When it is Multi-Line (AcceptsReturn = True, obviously) I need the width and height to stretch and take up the entire space.

Both of these triggers work perfectly in Run-Time, as running this code will show, but in Design-Time they both fail to work on the trigger condition. When using the "multiLineInTrigger" style, the textbox will have the height and width set statically (regardless of AcceptsReturn), but when using the "singleLineInTrigger" style, the controls will be stretched regardless of AcceptsReturn value.

Is there a solution for this issue? This has become quite troublesome and time-consuming for the development team because they do not know when it is working vs when it is not until compiling and running the application (which is a lengthy process).

Thanks.

Undo
  • 25,519
  • 37
  • 106
  • 129
Travis
  • 293
  • 1
  • 5
  • 13
  • Design time assumption is you are referencing VS2010 versus Expression Blend? – Aaron McIver Jan 04 '11 at 17:30
  • 1
    1) Try re-building the solution and check, this is first option. 2) Create a CustomTextBox by sub-class it from TextBox. In OnApplyTemplate apply this style within the code block DesignerProperties.GetIsInDesignMode(). So, this style will be applied alone to the design mode. Use this CustomTextBox. You are done. – Prince Ashitaka Jan 04 '11 at 17:56
  • @Aaron, Yes, this is in Visual Studio 2010, not expression. – Travis Jan 04 '11 at 18:23
  • @Prince Ashitaka, I've tried rebuilding the solution, to no avail. We do have some custom controls already, I will try handling the OnApplyTemplate and going with your solution. Is this the only solution though? I don't really think management would be too happy making a custom control for all the different controls we use just to handle this event. Thank you for the information. – Travis Jan 04 '11 at 18:26

1 Answers1

6

I've seen this problem many times and I've never seen a workaround for it, Triggers doesn't work in Visual Studio 2010 Designer. Hopefully they can get this fixed soon.

The only solution I can think of is to do the design work in Expression Blend 4 instead where this works perfectly. Might not be ideal but at the moment I don't think you have any other choise

Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266
  • I was afraid that might be the case. Thanks for the info, I'll check out expression blend and see if that's a solution in the mean time. – Travis Jan 04 '11 at 23:25