Как ссылаться на родительский элемент управления из стиля ControlTemplate в WPF? - PullRequest
1 голос
/ 01 июля 2010

У меня есть простой стиль для элементов управления ярлыками. Я хотел бы определить шаблон элемента управления внутри стиля с помощью кнопки, которую можно щелкнуть и которая установит для свойства видимости метки значение «Скрытый». Примерно так:

<Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Label}">
                <Border BorderThickness="1" Padding="4" CornerRadius="3"   
                        BorderBrush="Gray" Background="#FFA11616">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <ContentPresenter Grid.Column="0"/>
                        <Button Grid.Column="1" Width="16" Height="16" Padding="2" FontSize="9" Content="X">
                       <!-- THIS IS WRONG! HOW TO CREATE A TRIGGER FOR THIS BUTTON 
                            HERE AND HOW TO REFER TO THE LABEL? -->
                            <Button.Triggers>

                                <Trigger Property="Button.IsPressed" Value="True">
                                    <Setter Property="Visibility" Value="Hidden" />
                                </Trigger>
                            </Button.Triggers>
                        </Button>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

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

Спасибо.

Ответы [ 2 ]

2 голосов
/ 01 июля 2010

Я создал это с помощью Blend 4. По сути, вы хотите обработать событие «PreviewMouseButtonUp» на вашей кнопке с помощью EventTrigger.EventTrigger запустит Storyboard, который анимирует свойство UIElement.Visibility в значение «Скрытый» в верхней части дерева визуалов для стиля вашей метки.

Чтобы получить контроль над содержимым кнопки, выможно использовать свойство Tag в элементе управления меткой.В противном случае вам придется создать другое свойство зависимостей, а это означает, что подкласс Label.

Внутри стиля <Button/> будет выглядеть следующим образом:

<Button x:Name="button" Grid.Column="1" Padding="2" 
  FontSize="9" 
  Content="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"/>

...и так как вы можете поместить что-нибудь в свойство Tag, вы можете сделать это:

    <Label x:Name="label" Content="Label" 
      Style="{DynamicResource MessageLabel_WithCloseButton}">
        <Label.Tag>
            <StackPanel>
                <TextBlock>WOOT</TextBlock>
                <TextBlock>WOOT</TextBlock>
            </StackPanel>
        </Label.Tag>
    </Label>

Вот измененный полный стиль (я также изменил некоторые вещи для улучшения автоматического определения размера:

    <Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Label}">
                    <ControlTemplate.Resources>
                        <Storyboard x:Key="OnClick1">
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="border">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <Visibility>Hidden</Visibility>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </ControlTemplate.Resources>
                    <Border x:Name="border" BorderThickness="1" Padding="4" CornerRadius="3"   
                    BorderBrush="Gray" Background="#FFA11616">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <ContentPresenter Grid.Column="0" VerticalAlignment="Center" Margin="0,0,3,0"/>
                            <Button x:Name="button" Grid.Column="1" Padding="2" FontSize="9" Content="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"/>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <EventTrigger RoutedEvent="UIElement.PreviewMouseLeftButtonUp" SourceName="button">
                            <BeginStoryboard x:Name="OnClick1_BeginStoryboard" Storyboard="{StaticResource OnClick1}"/>
                        </EventTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Также обратите внимание, что EventTrigger находится на вашем ControlTemplate, а не на Button в вашем дереве. Но это может быть именно так, как Blend генерирует код.

1 голос
/ 01 июля 2010

Вы можете использовать ToggleButton вместо обычной кнопки, а затем просто использовать свойство IsChecked для триггера:

<Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Label}">
                <Border BorderThickness="1" Padding="4" CornerRadius="3"   
                BorderBrush="Gray" Background="#FFA11616">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <ContentPresenter Grid.Column="0"/>
                        <ToggleButton x:Name="CloseButton" Grid.Column="1" Width="16" Height="16" Padding="2" FontSize="9" Content="X"/>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger SourceName="CloseButton" Property="IsChecked" Value="True">
                        <Setter Property="Visibility" Value="Hidden" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...