문제

나는 단순히 WPF를 열고 싶다 팝업 지연으로, 일종의 a 툴팁.

이것을 어떻게 달성 할 수 있습니까?

그건 그렇고, Popup.popupanimation = popupanimation.fade ... 너무 빨리 사라집니다. 나는 거기에서 적어도 0.5 초를 원한다.

도움이 되었습니까?

해결책 3

우선 ...이 답변에 대한 크레딧은 에릭 버크. 그 대답했다 이 질문은 WPF 제자 그룹에 게시되었습니다. 나는이 답변을 stackoverflow에도 넣는 것이 유용 할 것이라고 생각했다.

기본적으로, 당신은 별개의 부울 킬키 프레임으로 팝업의 Isopen 속성을 애니메이션해야합니다.

다음 XAML을 확인하십시오 (쉽게 붙여 넣을 수 있습니다. Kaxaml 또는 다른 느슨한 XAML 편집 유틸리티) :

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
    <ContentPresenter>
        <ContentPresenter.ContentTemplate>
            <DataTemplate>
                <Grid>
                    <CheckBox
                        x:Name="cb"
                        Width="100"
                        Height="40"
                        Content="Hover Over Me"
                    />
                    <Popup
                        x:Name="popup"
                        Placement="Bottom"
                        PlacementTarget="{Binding ElementName=cb}"
                    >
                        <Border Width="400" Height="400" Background="Red"/>
                    </Popup>
                </Grid>
                <DataTemplate.Triggers>
                    <Trigger SourceName="cb" Property="IsMouseOver" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="bsb">
                                <Storyboard>
                                    <BooleanAnimationUsingKeyFrames
                                        Storyboard.TargetName="popup"
                                        Storyboard.TargetProperty="IsOpen"
                                        FillBehavior="HoldEnd"
                                    >
                                        <DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
                                     </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <StopStoryboard BeginStoryboardName="bsb"/>
                        </Trigger.ExitActions>
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ContentPresenter.ContentTemplate>
    </ContentPresenter>
</Page>

그의 원래 솔루션을 약간 수정했습니다. 마우스의 Isopen을 마우스 위에 트리거하는 것과 그와 같이 확인란을 확인하는 것입니다. 팝업을 만들려고 시도하면 툴팁이 조금 비슷합니다.

다른 팁

다음과 같은 방식으로 팝업에 적용 할 스타일을 만들 수 있습니다.

<Style x:Key="TooltipPopupStyle" TargetType="Popup">
    <Style.Triggers>
        <DataTrigger Binding="{Binding PlacementTarget.IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard x:Name="OpenPopupStoryBoard" >
                    <Storyboard>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame KeyTime="0:0:0.25" Value="True"/>
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
            <DataTrigger.ExitActions>
                <PauseStoryboard BeginStoryboardName="OpenPopupStoryBoard"/>
                <BeginStoryboard x:Name="ClosePopupStoryBoard">
                    <Storyboard>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame KeyTime="0:0:1" Value="False"/>
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.ExitActions>
        </DataTrigger>

        <Trigger Property="IsMouseOver" Value="True">
            <Trigger.EnterActions>
                <PauseStoryboard BeginStoryboardName="ClosePopupStoryBoard" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <PauseStoryboard BeginStoryboardName="OpenPopupStoryBoard"/>
                <ResumeStoryboard BeginStoryboardName="ClosePopupStoryBoard" />
            </Trigger.ExitActions>
        </Trigger>
    </Style.Triggers>
</Style>

그런 다음 사용하려면 마크 업을 작성할 때마다 다음과 비슷한 마크 업을 씁니다 (배치의 바인딩에주의하십시오).

<TextBlock x:Name="TargetControl" Text="Hover over me!" />
<Popup PlacementTarget="{Binding ElementName=TargetControl}" Style="{StaticResource TooltipPopupStyle}">
    <Border BorderBrush="Red" BorderThickness="1" Background="White">
        <TextBlock Text="This is a Popup behaving somewhat like the tooltip!" Margin="10" />
    </Border>
</Popup>

CPLOTTS가 붙여 넣은 답변은 양호하지만 귀하의 경우에 애니메이션이 Isopen 속성에 부착되어 효과적으로 제자리에 고정되어 직접 속성 설정, 바인딩 및 기타 방법을 통해 변경되는 것을 방지하기 때문에 귀하의 경우에 적용되지 않을 수 있습니다. 이로 인해 코드 사용 방식에 따라 코드와 함께 사용하기가 어려울 수 있습니다.

이 경우 지연 후 팝업을 열고 싶을 때 Dispatchertimer를 시작하는 것으로 전환합니다.

_popupTimer = new DispatcherTimer(DispatcherPriority.Normal);
_popupTimer.Interval = TimeSpan.FromMilliseconds(100);
_popupTimer.Tick += (obj, e) =>
{
  _popup.IsOpen = true;
};
_popupTimer.Start();

툴팁과 같은 동작의 경우 마우스 센터에서 수행 할 수 있습니다. 어떤 이유로 팝업 개구부를 취소하려면 (예 : 마우스가 팝업이 나타나기 전에 컨트롤을 떠나는 경우), 그냥 :

_popupTimer.Stop();

업데이트

주석에 cplotts가 멍청한 것처럼, 당신은 또한 설정하고 싶을 것입니다 _popup.IsOpen = false Mouseleave 이벤트의 일부 상황에서는 컨트롤과 팝업 사이의 마우스 입력 / 출구 이벤트를 처리하기위한 논리에 따라. 보통 맹목적으로 설정하고 싶지 않다는 점에 유의하십시오. IsOpen=false 모든 Mouseleave 이벤트에서 팝업이 나타날 때 그렇게 할 수 있기 때문입니다. 이것은 어떤 상황에서는 깜박 거리는 팝업으로 이어질 것입니다. 그래서 당신은 거기에 약간의 논리가 필요합니다.

System.Windows.Controls.ToolTip tp = new System.Windows.Controls.ToolTip();

System.Windows.Threading.DispatcherTimer tooltipTimer =
    new System.Windows.Threading.DispatcherTimer
    (
        System.Windows.Threading.DispatcherPriority.Normal
    );

private void TooltipInvalidCharacter()
{
    tp.Content =
        "A flie name cannot contain any of the following character :" +
        "\n" + "\t" + "\\  / : *  ?  \"  <  >  |";

    tooltipTimer.Interval = TimeSpan.FromSeconds(5);
    tooltipTimer.Tick += new EventHandler(tooltipTimer_Tick);
    tp.IsOpen = true;
    tooltipTimer.Start();       
}

void tooltipTimer_Tick(object sender, EventArgs e)
{
     tp.IsOpen = false;
     tooltipTimer.Stop();
}

마우스가 끝나는 한 팝업이 열려 있도록이 솔루션의 XAML을 확장 할 수 있습니다. 그런 다음 자동으로 사라집니다.

샘플을 다음과 같이 수정했습니다.

  1. 0.5 초 후에 Isopen을 False로 설정하는 "ClosePopop"애니메이션을 만듭니다. 나는 이것을 두 번 사용하기 때문에 이것을 자원으로 만들었습니다.
  2. Control의 ISMouseOver 트리거의 경우 ClosePopup 애니메이션을 시작하는 종료를 추가하십시오. 이를 통해 사용자는 마우스가 팝업을 닫기 전에 팝업 위로 이동할 수 있습니다. 나는이 애니메이션을 "bxb"라고 명명했습니다.
  3. 팝업의 ISMouseOver 속성에 트리거를 추가하십시오. 마우스 오버에서는 원래 "BXB"ClosePopup 애니메이션을 중지하고 제거하지 마십시오. 이것은 팝업을 보인다. 여기서 애니메이션을 제거하면 팝업이 닫히게됩니다.
  4. 팝업의 마우스 아웃에서 새로운 ClosePopup 애니메이션을 시작한 다음 "BXB"애니메이션을 제거하십시오. 마지막 단계는 중요합니다. 그렇지 않으면 첫 번째로 중지 된 "BXB"애니메이션이 팝업을 열어두기 때문입니다.

이 버전은 마우스가 끝나는 동안 팝 파란색으로 바뀝니다. Kaxaml.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 <DataTemplate x:Key="TooltipPopup">
  <Grid>
    <CheckBox
        x:Name="cb"
        Width="100"
        Height="40"
        Content="Hover Over Me"/>
    <Popup
        x:Name="popup"
        Placement="Bottom"
        PlacementTarget="{Binding ElementName=cb}">
        <Border x:Name="border" Width="400" Height="400" Background="Red"/>
    </Popup>
  </Grid>
  <DataTemplate.Resources>
    <Storyboard x:Key="ClosePopup">
        <BooleanAnimationUsingKeyFrames
                        Storyboard.TargetName="popup"
                        Storyboard.TargetProperty="IsOpen"
                        FillBehavior="Stop">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="False"/>
        </BooleanAnimationUsingKeyFrames>
    </Storyboard>
  </DataTemplate.Resources>
  <DataTemplate.Triggers>
    <Trigger SourceName="cb" Property="IsMouseOver" Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard x:Name="bsb" >
                <Storyboard>
                    <BooleanAnimationUsingKeyFrames
                        Storyboard.TargetName="popup"
                        Storyboard.TargetProperty="IsOpen"
                        FillBehavior="HoldEnd">
                        <DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
                    </BooleanAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <StopStoryboard BeginStoryboardName="bsb"/>
            <BeginStoryboard x:Name="bxb" Storyboard="{StaticResource ClosePopup}"/>
        </Trigger.ExitActions>
    </Trigger>
    <Trigger SourceName="popup" Property="IsMouseOver" Value="True">
        <Setter TargetName="border" Property="Background" Value="Blue"/>
        <Trigger.EnterActions>
            <StopStoryboard BeginStoryboardName="bxb"/>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <BeginStoryboard Storyboard="{StaticResource ClosePopup}"/>
            <RemoveStoryboard BeginStoryboardName="bxb"/>
        </Trigger.ExitActions>
    </Trigger>
  </DataTemplate.Triggers>
 </DataTemplate>
</Page>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top