Установка высоты RowDefinition из StaticResource

В моем стиле WPF я определил высоту строки стандартной сетки, которую я хотел бы применить к нескольким местам:

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

Однако это не работает, когда я хотел бы применить это так:

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

Вместо этого мне нужно создать полный стиль, например:

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

Как видно из прокомментированной строки, пытающейся ссылаться на числовую константу в определении стиля, также не работает, но имеет значение "hardcoded".

Теперь я просмотрел его, и я предполагаю, что это связано с тем, что тип, связанный с свойством Height, является GridLength, и он каким-то образом не может автоматически использовать двойное значение при отправке с другого ресурса...

Проблема заключается в том, что, похоже, не существует способа создания объекта GridLength из XAML. Свойство Value - только для чтения. Так что что-то вроде этого тоже не работает:

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

Есть ли способ заставить это работать, или я должен просто забыть использовать эту константу и просто использовать стиль RowDefinition с жестко заданным значением вместо константы?

Ответы

Ответ 1

Когда вы получаете "жесткий код", процессор XAML ищет конвертер, который может преобразовать его из строки в нужный тип. Даже ваш ресурс TableRowHeight использует DoubleConverter для создания. GridLength использует GridLengthConverter.

Таким образом, в компиляторе нет автоматического преобразования/преобразования - WPF необходимо явно искать класс и вызывать метод конвертации. В случае StaticResource он пропускает этот шаг.

Привязки используют преобразователи типов, поэтому следующее будет работать так, как вы ожидаете:

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

Это работает, потому что GridLengthConverter знает, как конвертировать из Double. В вашем случае это не обязательно. Если вы инициализируете ресурс GridLength так же, как вы инициализировали Double (внутри тегов), преобразование строки будет вызываться до назначения ресурса:

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

Тогда вы сможете напрямую вызвать ресурс.

Ответ 2

вам нужно будет создать ресурс типа GridLength, чтобы применить его как RowDefinition.Height от типа GridLength:

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

Это будет работать в любом случае, если вы хотите применить его.

Ответ 3

Попробуйте следующее:

    <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>
     ....