TemplateBinding к RowDefinition.Height игнорируется в ContentControl - PullRequest
1 голос
/ 26 июня 2011

Описание: У меня есть пользовательский элемент управления контентом, и я пытаюсь включить некоторые внешние настройки через свойства зависимостей.В основном это панель декоратора с двумя рядами сетки, верхняя - заголовок, нижняя - содержимое (через ContentPresenter).

Есть 3 элемента, которые связаны с шаблоном (через TemplateBinding), HeaderHeight, TextSize и Header (каждый из них имеет свойство зависимости соответствующего типа).

Проблема: В то время как две привязки работают идеально (даже во время разработки), третья - нет.Привязки FontSize="{TemplateBinding TextSize}" и Text="{TemplateBinding Header}" работают, но <RowDefinition Height="{TemplateBinding HeaderHeight}" /> не работает .

Сетка разделяет высоты строк 50/50, независимо от того, какое значение я установилсвойство HeaderHeight для.Он даже не принимает значение по умолчанию из метаданных DP.

Вопрос: В чем проблема в этом сценарии?Почему две другие привязки работают без проблем, а эта ведет себя так, как будто привязки вообще нет?

Примечание: Если я установил DataContext = this в конструкторе и заменил {TemplateBinding HeaderHeight} с {Binding HeaderHeight} проблема исчезает и работает как задумано.Но я хотел бы знать, почему мне не нужно делать то же самое с другими привязками, чтобы они работали.

XAML (Themes / Generic.xaml):

<Style TargetType="local:KaiPanel">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:KaiPanel">
                <Grid x:Name="LayoutRoot">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="{TemplateBinding HeaderHeight}" />
                        <RowDefinition />
                    </Grid.RowDefinitions>

                    <Grid Grid.Row="0">
                        <Border>
                            <TextBlock FontSize="{TemplateBinding TextSize}" 
                                       Text="{TemplateBinding Header}" />
                        </Border>
                    </Grid>

                    <Grid Grid.Row="1">
                        <Border>
                            <ContentPresenter />
                        </Border>
                    </Grid>

                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Контроль содержимого (C #):

public class KaiPanel : ContentControl
{
    public KaiPanel()
    {
        this.DefaultStyleKey = typeof(KaiPanel);
    }

    public static readonly DependencyProperty TextSizeProperty =
        DependencyProperty.Register("TextSize", typeof(double), typeof(KaiPanel), new PropertyMetadata(15.0));

    public double TextSize
    {
        get { return (double)GetValue(TextSizeProperty); }
        set { SetValue(TextSizeProperty, value); }
    }

    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register("Header", typeof(String), typeof(KaiPanel), new PropertyMetadata(""));

    public String Header
    {
        get { return (String)GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }

    public static readonly DependencyProperty HeaderHeightProperty =
        DependencyProperty.Register("HeaderHeight", typeof(GridLength), typeof(KaiPanel), new PropertyMetadata(new GridLength(40)));

    public GridLength HeaderHeight
    {
        get { return (GridLength)GetValue(HeaderHeightProperty); }
        set { SetValue(HeaderHeightProperty, value); }
    }
}

Использование пользовательского контроля (XAML):

<UserControl ...>

    <Grid x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <StackPanel x:Name="buttonsStackPanel" Grid.Column="0" VerticalAlignment="Center">
            <!-- Some buttons here -->
        </StackPanel>

        <Grid Grid.Column="1">
            <controls:KaiPanel x:Name="contentPanel">
                <navigation:Frame x:Name="contentFrame" Source="KP">
                    <navigation:Frame.UriMapper>
                        <uriMapper:UriMapper>
                            <uriMapper:UriMapping Uri="KP" MappedUri="/Views/Kornelijepetak.xaml" />
                            <uriMapper:UriMapping Uri="KAI" MappedUri="/Views/KaiNetwork.xaml" />
                        </uriMapper:UriMapper>
                    </navigation:Frame.UriMapper>
                </navigation:Frame>
            </controls:KaiPanel>
        </Grid>
    </Grid>
</UserControl>

1 Ответ

0 голосов
/ 27 июня 2011

К сожалению, кажется, что вы пытаетесь сделать, требуется больше, чем просто привязка данных. RowDefinition не является подклассом FrameworkElement и не соответствует ни одному из других критериев, указанных в документации по привязке данных MSDN Silverlight , поэтому его нельзя использовать в качествецель привязки.

То, что вы хотите сделать, возможно, но, к сожалению, это требует немного больше кода.

Во-первых, добавьте поле для основной сетки (я назвал это mainGrid) в ваш класс KaiPanel.Затем переопределите метод OnApplyTemplate в этом классе, чтобы получить основной Grid из шаблона и сохранить ссылку на него в поле mainGrid:

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        mainGrid = GetTemplateChild("LayoutRoot") as Grid;
        SetHeaderRowHeight();
    }

Это вызывает метод, который обновляетвысота первого ряда сетки.Этот метод выглядит следующим образом:

    private void SetHeaderRowHeight()
    {
        if (mainGrid != null)
        {
            mainGrid.RowDefinitions[0].Height = HeaderHeight;
        }
    }

Я признаю, что не уверен на 100%, что OnApplyTemplate вызывается после установки DP.Кажется, что это так (быстрый тест, казалось, подтвердил это), но все, что я смог найти, чтобы поддержать это, было это сообщение на форумах Silverlight .Если вы обнаружите, что это не так, вам нужно зарегистрировать PropertyChangedCallback на HeaderHeight DP, который также вызовет этот метод SetHeaderRowHeight.

См. Также http://forums.silverlight.net/forums/t/76992.aspx#183089.

...