Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting the RowDefinition Height from StaticResource

Tags:

c#

wpf

In my WPF style I have defined a standard grid row height I'd like to apply to several places like so:

<system:Double x:Key="TableRowHeight">22</system:Double>

However it does not work when I'd like to apply this like so:

<RowDefinition Height="{StaticResource TableRowHeight}"/>

Instead I need to create a complete style like:

<Style x:Key="GridTableRow" TargetType="{x:Type RowDefinition}">
    <!--<Setter Property="Height" Value="{StaticResource TableRowHeight}"/>-->
    <Setter Property="Height" Value="22"/>
</Style>

As can be seen from the commented out line trying to reference the numeric constant within the Style definition does not work either, but the "hardcoded" value does.

Now I've looked it up and I guess it is because the type associated with the Height property is GridLength and it somehow does not manage to automatically cast the double value when comming from another resource...

The problem is that there does not seem to be a way of creating a GridLength object from XAML. The Value propery is readonly. So something like this does not work either:

<Style x:Key="GridTableRow" TargetType="{x:Type RowDefinition}">
    <Setter Property="Height">
        <Setter.Value>
            <GridLength Value="{StaticResource TableRowHeight}"/>
        </Setter.Value>
    </Setter>
</Style>

Is there a way to get this to work, or should I just forget using that constant and just use the RowDefinition style with the hardcoded value in place of the constant?

like image 951
bjavor Avatar asked Sep 05 '13 12:09

bjavor


3 Answers

When you "hard code" values, the XAML processor looks up a converter that can convert it from string to the necessary type. Even your TableRowHeight resource is using DoubleConverter to be created. GridLength uses GridLengthConverter.

So there is no automatic cast / conversion happening in the compiler -- WPF needs to explicitly look up a class and call a convert method. In the case of StaticResource, it skips this step.

Bindings do use type converters though, so the following would work as you expect:

<RowDefinition Height="{Binding Source={StaticResource TableRowHeight}}" />

This works because GridLengthConverter knows how to convert from Double. In your case, this should not be necessary, though. If you initialize a GridLength resource in the same way you initialized Double (inside the tags), the string conversion will be called before the resource is assigned:

<GridLength x:Key="TableRowHeight">22</GridLength>

Then you would be able to call the resource directly.

like image 109
nmclean Avatar answered Nov 05 '22 19:11

nmclean


Try this:

    <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:t="clr-namespace:System.Windows;assembly=PresentationFramework">
    <Window.Resources>
        <t:GridLength x:Key="gridHeight">50</t:GridLength>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="{StaticResource gridHeight}"></RowDefinition>
        </Grid.RowDefinitions>
     ....
like image 28
ninja hedgehog Avatar answered Nov 05 '22 21:11

ninja hedgehog


you will have to create the resource of type GridLength in order to apply as RowDefinition.Height is of type GridLength:

<window:GridLength x:Key="TableRowHeight">50</window:GridLength>

This will work in anyway you want to apply it.

like image 2
Nitin Avatar answered Nov 05 '22 20:11

Nitin