سؤال

أريد ببساطة فتح WPF يظهر فجأة مع تأخير، نوع من مثل أ تلميح.

كيف يمكنني تحقيق ذلك؟

وبالمناسبة، Popup.PopupAnimation = PopupAnimation.Fade ...يتلاشى بسرعة كبيرة.أريد على الأقل نصف ثانية هناك.

هل كانت مفيدة؟

المحلول 3

أولا ...يعود الفضل في هذه الإجابة إلى إريك بيرك.هو أجاب تم نشر هذا السؤال بالذات في مجموعة WPF Disciples.اعتقدت أنه سيكون من المفيد نشر هذه الإجابة على StackOverflow أيضًا.

في الأساس، تحتاج إلى تحريك خاصية IsOpen في النافذة المنبثقة باستخدام DiscreteBooleanKeyFrame.

تحقق من ملف xaml التالي (والذي يمكن لصقه بسهولة في ملف كاكسامل أو أداة تحرير 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 عند تمرير الماوس فوقه مقابل تحديد CheckBox كما فعل.كل ذلك في محاولة لجعل النافذة المنبثقة تتصرف مثل ToolTip إلى حدٍ ما.

نصائح أخرى

ويمكنك إنشاء نمط ليتم تطبيقها على قافزة على النحو التالي:

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

وبعد ذلك، كلما كنت ترغب في استخدامه، وكنت إرسال العلامات مشابهة لهذه (لاحظ وملزمة لPlacementTarget):

<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();

للحصول على سلوك يشبه تلميح الأدوات، يمكن القيام بذلك على MouseEnter.إذا كنت تريد إلغاء فتح النافذة المنبثقة لسبب ما (على سبيل المثال، إذا ترك الماوس عنصر التحكم قبل ظهور النافذة المنبثقة)، فما عليك سوى:

_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. قم بإنشاء رسم متحرك "ClosePopop" والذي يقوم بتعيين IsOpen إلى False بعد 0.5 ثانية.لقد جعلت هذا موردًا لأنه تم استخدامه مرتين.
  2. بالنسبة لمشغل IsMouseOver الخاص بعنصر التحكم، قم بإضافة ExitAction الذي يبدأ الرسوم المتحركة ClosePopup.وهذا يمنح المستخدم فرصة لتحريك الماوس فوق النافذة المنبثقة قبل إغلاقها.لقد قمت بتسمية هذه الرسوم المتحركة "bxb"
  3. قم بإضافة مشغل إلى خاصية IsMouseOver الخاصة بالنافذة المنبثقة.عند تمرير الماوس، قم بإيقاف (ولكن لا تقم بإزالة) الرسوم المتحركة ClosePopup الأصلية "bxb".وهذا يترك النافذة المنبثقة مرئية؛ستؤدي إزالة الرسوم المتحركة هنا إلى إغلاق النافذة المنبثقة.
  4. عند خروج الماوس من النافذة المنبثقة، ابدأ رسمًا متحركًا جديدًا لـ ClosePopup ثم قم بإزالة الرسم المتحرك "bxb".تعتبر الخطوة الأخيرة حاسمة لأنه بخلاف ذلك فإن الرسوم المتحركة الأولى المتوقفة "bxb" ستبقي النافذة المنبثقة مفتوحة.

يقوم هذا الإصدار بتحويل النافذة إلى اللون الأزرق أثناء وضع الماوس فوقها حتى تتمكن من رؤية تسلسل الأحداث بها كاكسامل.

<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