Изменение шаблона Expander на основе свойств - PullRequest
0 голосов
/ 10 ноября 2010

Ниже приведен раздел моего настроенного шаблона Expander:

<Grid 
    x:Name="ExpandSiteContainer" 
    Visibility="Visible" 
    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
    Margin="{TemplateBinding Padding}" 
    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
    DockPanel.Dock="Bottom">
        <!--<Grid.Height>
            <MultiBinding Converter="{StaticResource multiplyConverter}">
                <Binding Path="ActualHeight" ElementName="ExpandSite"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Grid.Height>-->
        <Grid.Width>
            <MultiBinding Converter="{StaticResource multiplyConverter}">
                <Binding Path="ActualWidth" ElementName="ExpandSite"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Grid.Width>
        <Grid.Tag>
            <sys:Double>0.0</sys:Double>
        </Grid.Tag>
        <ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden">
            <ContentPresenter x:Name="ExpandSite" Focusable="false" VerticalAlignment="Top"/>
        </ScrollViewer>
</Grid>

У меня также определен следующий триггер:

<Trigger Property="IsExpanded" Value="true">
    <Trigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Storyboard.TargetName ="ExpandSiteContainer" Storyboard.TargetProperty = "Tag" To="1.0" Duration ="0:0:0.25" />
            </Storyboard>
        </BeginStoryboard>
    </Trigger.EnterActions>
    <Trigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Storyboard.TargetName ="ExpandSiteContainer" Storyboard.TargetProperty ="Tag" To="0" Duration ="0:0:0.25"/>
            </Storyboard>
        </BeginStoryboard>
    </Trigger.ExitActions>
</Trigger>

Что происходит, когда расширитель будет скользить открытым / закрытымиспользуя определенные выше раскадровки при каждом изменении свойства IsExpanded.

Я хотел бы как-то «передать» значения, которые изменят его поведение:

  1. Обратите внимание, чтораздел Grid.Height в шаблоне закомментирован.Это закомментировано, потому что сейчас мой расширитель расширяется вправо, и я хочу изменить только ширину сетки.Могу ли я что-нибудь сделать, чтобы в зависимости от ExpandDirection экспандера я мог изменить поведение шаблона (можно ли изменить высоту, если ExpandDirection вверх или вниз, и ширину, если ExpandDirection слева или справа)?

  2. Есть ли способ изменить продолжительность анимации, определенную в шаблоне, для разных расширителей, или мне нужно создавать отдельные шаблоны?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 10 ноября 2010

для вашего второго вопроса,

, почему бы не добавить свойство зависимости (например, "time") в свой пользовательский расширитель, а затем связать с ним свойство Duration двойной анимации?После того, как вы сможете использовать его таким образом

<local:MyCustomExpander Time="2"/>

, и ваш шаблон по умолчанию получит это значение.(Я сам не пробовал, поэтому не могу гарантировать эффективность)

0 голосов
/ 10 ноября 2010

В вопросе 1 вы можете использовать триггеры для выбора поведения расширения на основе ExpandDirection.удалите Grid.Width и Grid.Height из Grid, а затем добавьте это в триггеры вашего шаблона:

<Trigger Property="ExpandDirection" Value="Down">
    <Setter TargetName="ExpandSiteContainer" Property="Height">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource multiplyConverter}">
                <Binding Path="ActualHeight" ElementName="ExpandSite"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Trigger>
<Trigger Property="ExpandDirection" Value="Right">
    <Setter TargetName="ExpandSiteContainer" Property="Width">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource multiplyConverter}">
                <Binding Path="ActualWidth" ElementName="ExpandSite"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Trigger>

Для вопроса 2, я думаю, ответ может быть: нет.Проблема в том, что WPF в конечном итоге попытается заморозить анимацию, потому что она является частью Style, и это затрудняет выполнение всего, что изменяет продолжительность.(Например, если вы попытаетесь связать данные с анимацией Duration, вы получите ошибку во время инициализации, потому что WPF пытается заморозить Storyboard, что быстро выдает исключение, чтобы сказать, что оно не может быть заморожено.)Я понимаю, что причина, по которой стили замораживают свои ресурсы, заключается в том, что это позволяет более эффективно распределять ресурсы между несколькими экземплярами стиля.Как сказано в http://msdn.microsoft.com/library/ms742868

Нельзя использовать динамические ссылки на ресурсы или выражения привязки данных для установки значений свойств раскадровки или анимации.Это потому, что все внутри стиля должно быть поточно-ориентированным, а система синхронизации должна заморозить объекты Storyboard, чтобы сделать их поточно-ориентированными.Storyboard не может быть заморожен, если он или его дочерние временные шкалы содержат ссылки на динамические ресурсы или выражения привязки данных.

Я не совсем уверен, почему «все внутри стиля должно быть поточно-ориентированным».Я вижу, что это будет необходимо для стилей, которые используются в нескольких потоках (например, стили по умолчанию для элементов управления).Возможно, они просто обеспечивают соблюдение всех стилей для согласованности.Но в любом случае, похоже, что анимации внутри стилей не содержат динамических значений любого вида, что говорит о том, что вы не сможете выполнить 2-е действие, о котором вы просите.

...