স্ক্রিনে থাকতে ডাব্লুপিএফ টুলটিপ জোর করে


119

আমার কাছে একটি লেবেলের একটি সরঞ্জামদণ্ড রয়েছে এবং ব্যবহারকারীটি মাউসকে অন্য একটি নিয়ন্ত্রণে না নিয়ে যাওয়া পর্যন্ত এটি উন্মুক্ত থাকতে চাই want

আমি টুলটিপে নীচের বৈশিষ্ট্যগুলি চেষ্টা করেছি:

StaysOpen="True"

এবং

ToolTipService.ShowDuration = "60000"

তবে উভয় ক্ষেত্রেই টুলটিপটি ঠিক 5 সেকেন্ডের জন্য প্রদর্শিত হয়।

কেন এই মানগুলিকে উপেক্ষা করা হচ্ছে?


সম্পত্তিটির জন্য কোথাও সর্বাধিক মান প্রয়োগ করা হয় ShowDuration, মনে করুন এটি এমন একটি 30,000। এর থেকে বড় কিছু এবং এটি ডিফল্ট হয়ে যাবে 5000
ডেনিস

2
@ ডেনিস: আমি ডাব্লুপিএফ 3.5 এর সাথে এটি পরীক্ষা করেছি এবং ToolTipService.ShowDuration="60000"কাজ করেছি। এটিতে ফিরতে ডিফল্ট হয়নি 5000
এম ডুডলি

@ এমডিডুডলি: টুলটিপটি কি আসলে 60000 মিমি খোলা থাকে? আপনি ToolTipService.ShowDurationসম্পত্তিটি যে কোনও মান> = 0 (ইনট 32.ম্যাক্সভ্যালুতে) সেট করতে পারেন তবে টুলটিপটি দৈর্ঘ্যের জন্য খোলা থাকবে না।
ডেনিস

2
@ ডেনিস: হ্যাঁ, এটি ঠিক 60 সেকেন্ডের জন্য উন্মুক্ত ছিল। এই উইন্ডোজ 7. হয়
এম ডাডলি

@ এমডিডুডলি: পার্থক্য হতে পারে। উইন্ডোজ এক্সপির বিপরীতে যখন আমি বিকাশ করছিলাম তখন থেকেই এটি ছিল জ্ঞান।
ডেনিস

উত্তর:


113

এই কোডটি আরম্ভের অংশে রাখুন।

ToolTipService.ShowDurationProperty.OverrideMetadata(
    typeof(DependencyObject), new FrameworkPropertyMetadata(Int32.MaxValue));

এটি আমার জন্য কাজ করা একমাত্র সমাধান ছিল। প্লেসমেন্ট সম্পত্তি শীর্ষে সেট করতে আপনি এই কোডটি কীভাবে মানিয়ে নিতে পারেন? new FrameworkPropertyMetadata("Top")কাজ করে না
অবৈধব্রেইন এক্সসেপশন

6
আমি এটিকে (প্রায় years বছর পরে, দুঃখিত) সঠিক উত্তর হিসাবে চিহ্নিত করেছি কারণ এটি আসলে উইন্ডোজের সমস্ত সমর্থিত সংস্করণগুলিতে কাজ করে এবং এটি 49 দিনের জন্য উন্মুক্ত রাখে, যা যথেষ্ট দীর্ঘ হওয়া উচিত: পি
টিমোথিপ

1
আমি এটিকে আমার উইন্ডো_লয়েড ইভেন্টে রেখেছি এবং এটি দুর্দান্ত কাজ করে। কেবলমাত্র আপনাকে যা করতে হবে তা নিশ্চিত করে নেওয়া উচিত যে আপনি আপনার এক্সএএমএল-এ যে কোনও "টুলটিপসপস.সোচডিউরেশন" সেট করেছেন, সেগুলি থেকে মুক্তি পেয়েছেন, এক্সএএমএল-এ আপনি যে সময়সীমা নির্ধারণ করেছেন তা এই কোডটি অর্জন করার চেষ্টা করছে এমন আচরণকে ওভাররাইড করবে। সমাধান সরবরাহ করার জন্য জন হুইটারকে ধন্যবাদ।
নিকো

1
এফডব্লিউআইডাব্লু, আমি একে একে একে একে পছন্দ করি কারণ এটি বিশ্বব্যাপী - আমি চাই আমার অ্যাপ্লিকেশনটির সমস্ত সরঞ্জামদণ্ড আরও ধোঁকা ছাড়াই দীর্ঘক্ষণ স্থির থাকে। এটি করার পরেও আপনি যথাযথভাবে অন্যান্য উত্তরের মতো প্রাসঙ্গিক-নির্দিষ্ট জায়গাগুলিতে একটি ছোট মান প্রয়োগ করতে পারবেন। (তবে সর্বদা বরাবর, আপনি যদি অ্যাপ্লিকেশন হন তবে এটি কেবল বৈধ - যদি আপনি একটি নিয়ন্ত্রণ গ্রন্থাগার বা অন্য কিছু লেখেন তবে আপনাকে অবশ্যই প্রাসঙ্গিক-নির্দিষ্ট সমাধানগুলি ব্যবহার করতে হবে ; গ্লোবাল স্টেট আপনার সাথে খেলতে হবে না))
মিরাল

1
এটি বিপজ্জনক হতে পারে! ডাবল গণনা করে টাইমার অন্তর সেট করার সময় ডাব্লুপিএফ অভ্যন্তরীণভাবে টাইমস্প্যান ব্যবহার করে .ফর্মমিলিসেকেন্ডগুলি ()) এর অর্থ হ'ল যখন ইন্টারভাল সম্পত্তি ব্যবহার করে টাইমারটিতে মান প্রয়োগ করা হয় আপনি ArgumentOutOfRangeException পেতে পারেন।
জানুয়ারী

190

TooltipService.ShowDuration কাজ করে তবে আপনার এটি অবশ্যই সরঞ্জামটিপযুক্ত বস্তুর উপর সেট করতে হবে:

<Label ToolTipService.ShowDuration="12000" Name="lblShowTooltip" Content="Shows tooltip">
    <Label.ToolTip>
        <ToolTip>
            <TextBlock>Hello world!</TextBlock>
        </ToolTip>
    </Label.ToolTip>
</Label>

আমি বলব যে এই নকশাটি বেছে নেওয়া হয়েছে কারণ এটি বিভিন্ন নিয়ন্ত্রণে বিভিন্ন টাইমআউটগুলির সাথে একই সরঞ্জামদণ্ডকে অনুমতি দেয়।


4
এটি আপনাকে ToolTipস্পষ্ট ছাড়াই সরাসরি সামগ্রীর বিষয়বস্তু নির্দিষ্ট করার অনুমতি দেয় <ToolTip>যা বাধ্যতামূলক সহজতর করতে পারে।
নভিক

15
বিশ্বব্যাপী নয়, এটি প্রাসঙ্গিক নির্দিষ্ট হওয়ায় এটি নির্বাচিত উত্তর হওয়া উচিত।
ভ্লাদ

8
সময়কালটি মিলি সেকেন্ডে। ডিফল্টটি 5000 হয় above উপরের কোডটি 12 সেকেন্ড নির্দিষ্ট করে।
কনটাঙ্গো

1
আপনি যদি একই সরঞ্জামটিপ উদাহরণটি একাধিক নিয়ন্ত্রণের সাথে ব্যবহার করেন তবে তাড়াতাড়ি বা পরে "ইতিমধ্যে ভিন্ন পিতামাতার ভিজ্যুয়াল শিশু" ব্যতিক্রম পাবেন।
বসন্তের 76

1
এটির সঠিক উত্তর হওয়ার মূল কারণটি হ'ল এটি এক্সএএমএল কোডের মধ্যেই সঠিক উচ্চ স্তরের প্রোগ্রামিংয়ের মনোভাব এবং লক্ষ্য করা সহজ। অন্য সমাধান হ'ল ক্যান্ডা হ্যাকি এবং ভার্বোজ পয়েন্টটি ছাড়াও এটি বিশ্বব্যাপী। আমি বেশিরভাগ লোককে বাজি দিয়েছি যারা ব্যবহার করে যে তারা এক সপ্তাহে এটি কীভাবে করেছিল তা ভুলে গেছে।
j রিভ

15

এটিও আজ রাতে আমাকে পাগল করে তুলেছিল। আমি ToolTipইস্যুটি পরিচালনা করতে একটি সাবক্লাস তৈরি করেছি । আমার জন্য। নেট 4.0 এ, ToolTip.StaysOpenসম্পত্তিটি "সত্যই" খোলা থাকে না।

নীচের ক্লাসে, সম্পত্তি ToolTipEx.IsReallyOpenপরিবর্তে নতুন সম্পত্তি ব্যবহার করুন ToolTip.IsOpen। আপনি চান নিয়ন্ত্রণ পেতে হবে। Debug.Print()কলটির মাধ্যমে , আপনি ডিবাগার আউটপুট উইন্ডোতে দেখতে পারেন ঠিক কতবার this.IsOpen = falseবলা হয়! এত কিছুর জন্য StaysOpen, নাকি আমার বলা উচিত "StaysOpen"? উপভোগ করুন।

public class ToolTipEx : ToolTip
{
    static ToolTipEx()
    {
        IsReallyOpenProperty =
            DependencyProperty.Register(
                "IsReallyOpen",
                typeof(bool),
                typeof(ToolTipEx),
                new FrameworkPropertyMetadata(
                    defaultValue: false,
                    flags: FrameworkPropertyMetadataOptions.None,
                    propertyChangedCallback: StaticOnIsReallyOpenedChanged));
    }

    public static readonly DependencyProperty IsReallyOpenProperty;

    protected static void StaticOnIsReallyOpenedChanged(
        DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        ToolTipEx self = (ToolTipEx)o;
        self.OnIsReallyOpenedChanged((bool)e.OldValue, (bool)e.NewValue);
    }

    protected void OnIsReallyOpenedChanged(bool oldValue, bool newValue)
    {
        this.IsOpen = newValue;
    }

    public bool IsReallyOpen
    {
        get
        {
            bool b = (bool)this.GetValue(IsReallyOpenProperty);
            return b;
        }
        set { this.SetValue(IsReallyOpenProperty, value); }
    }

    protected override void OnClosed(RoutedEventArgs e)
    {
        System.Diagnostics.Debug.Print(String.Format(
            "OnClosed: IsReallyOpen: {0}, StaysOpen: {1}", this.IsReallyOpen, this.StaysOpen));
        if (this.IsReallyOpen && this.StaysOpen)
        {
            e.Handled = true;
            // We cannot set this.IsOpen directly here.  Instead, send an event asynchronously.
            // DispatcherPriority.Send is the highest priority possible.
            Dispatcher.CurrentDispatcher.BeginInvoke(
                (Action)(() => this.IsOpen = true),
                DispatcherPriority.Send);
        }
        else
        {
            base.OnClosed(e);
        }
    }
}

ছোট ভাড়া: মাইক্রোসফ্ট কেন DependencyPropertyপ্রোপার্টিগুলিকে (গেটার্স / সেটটার) ভার্চুয়াল তৈরি করে নি তাই আমরা সাবক্লাসে পরিবর্তনগুলি গ্রহণ / প্রত্যাখ্যান / সমন্বয় করতে পারি? বা virtual OnXYZPropertyChangedপ্রতিটি জন্য একটি করা DependencyProperty? বিতৃষ্ণা।

--- সম্পাদনা ---

এক্সএএমএল সম্পাদকের উপরে আমার সমাধানটি অদ্ভুত দেখাচ্ছে - টুলটিপটি সর্বদা দেখায়, ভিজ্যুয়াল স্টুডিওতে কিছু পাঠ্য অবরুদ্ধ করে!

এখানে এই সমস্যাটি সমাধানের আরও ভাল উপায়:

কিছু এক্সএএমএল:

<!-- Need to add this at top of your XAML file:
     xmlns:System="clr-namespace:System;assembly=mscorlib"
-->
<ToolTip StaysOpen="True" Placement="Bottom" HorizontalOffset="10"
        ToolTipService.InitialShowDelay="0" ToolTipService.BetweenShowDelay="0"
        ToolTipService.ShowDuration="{x:Static Member=System:Int32.MaxValue}"
>This is my tooltip text.</ToolTip>

কিছু কোড:

// Alternatively, you can attach an event listener to FrameworkElement.Loaded
public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    // Be gentle here: If someone creates a (future) subclass or changes your control template,
    // you might not have tooltip anymore.
    ToolTip toolTip = this.ToolTip as ToolTip;
    if (null != toolTip)
    {
        // If I don't set this explicitly, placement is strange.
        toolTip.PlacementTarget = this;
        toolTip.Closed += new RoutedEventHandler(OnToolTipClosed);
    }
}

protected void OnToolTipClosed(object sender, RoutedEventArgs e)
{
    // You may want to add additional focus-related tests here.
    if (this.IsKeyboardFocusWithin)
    {
        // We cannot set this.IsOpen directly here.  Instead, send an event asynchronously.
        // DispatcherPriority.Send is the highest priority possible.
        Dispatcher.CurrentDispatcher.BeginInvoke(
            (Action)delegate
                {
                    // Again: Be gentle when using this.ToolTip.
                    ToolTip toolTip = this.ToolTip as ToolTip;
                    if (null != toolTip)
                    {
                        toolTip.IsOpen = true;
                    }
                },
            DispatcherPriority.Send);
    }
}

উপসংহার: ক্লাস সম্পর্কে কিছু আলাদা ToolTipএবং ContextMenu। উভয়েরই "পরিষেবা" শ্রেণি রয়েছে, যেমন ToolTipServiceএবং ContextMenuServiceনির্দিষ্ট বৈশিষ্ট্যগুলি পরিচালনা করে এবং উভয়েরই Popupপ্রদর্শনের সময় "গোপন" পিতামাতার নিয়ন্ত্রণ হিসাবে ব্যবহার করা হয়। অবশেষে, আমি লক্ষ্য করেছি ওয়েবে সমস্ত এক্সএএমএল টুলটিপ উদাহরণ ToolTipসরাসরি ক্লাস ব্যবহার করে না । পরিবর্তে, তারা এস StackPanelসহ একটি এম্বেড করে TextBlock। যে জিনিসগুলি আপনাকে বলতে বাধ্য করে: "হুঁ ..."


1
আপনার উত্তরের জন্য কেবলমাত্র সম্পূর্ণতার জন্য আপনার আরও বেশি ভোট পাওয়া উচিত। আমার কাছ থেকে +1
হান্নিশ

টুলটিপসেসওয়ার্সকে প্যারেন্ট উপাদানগুলিতে স্থাপন করা দরকার, উপরে মার্টিন কোনিসেকের উত্তর দেখুন।
জেসন মারতাজায়া

8

আপনি সম্ভবত টুলটিপের পরিবর্তে পপআপ ব্যবহার করতে চান, যেহেতু টুলটিপ ধরে নিয়েছে যে আপনি এটি পূর্বনির্ধারিত ইউআই-মানক উপায়ে ব্যবহার করছেন।

স্টায়স ওপেন কেন কাজ করে না তা আমি নিশ্চিত নই, তবে এমএসডিএন-তে ডকুমেন্ট হিসাবে শোডিউরেশন কাজ করে - এটি প্রদর্শিত সময় যখন টুলটিপ প্রদর্শিত হয় তার পরিমাণ। পার্থক্যটি দেখতে এটি একটি অল্প পরিমাণে (উদাহরণস্বরূপ 500 মেসি) সেট করুন।

আপনার ক্ষেত্রে কৌতুকটি "শেষ অবধি নিয়ন্ত্রণ" অবস্থা বজায় রাখছে তবে আপনি যদি একবার পপআপ ব্যবহার করেন তবে স্থান নির্ধারণের লক্ষ্য এবং বিষয়বস্তুকে গতিশীলভাবে পরিবর্তন করতে (মোটামুটি বা বাঁধাইয়ের মাধ্যমে) পরিবর্তন করা মোটামুটি হালকা হওয়া উচিত, বা যদি আপনি একাধিক ব্যবহার করছেন তবে সর্বশেষ দৃশ্যমান পপআপ লুকিয়ে রাখছেন।

পপআপগুলির সাথে উইন্ডো পুনরায় আকার দেওয়ার এবং চলমান (পপআপগুলি ডাব্লু / পাত্রে ডাবলু করে না) এমন কিছু গ্যাটাচ রয়েছে, যাতে আপনি আচরণটি টুইট করার সময় আপনার মনেও থাকতে পারে। আরও তথ্যের জন্য এই লিঙ্কটি দেখুন ।

আছে HTH।


3
এছাড়াও সাবধান থাকুন যে পপআপগুলি সবসময় সমস্ত ডেস্কটপ অবজেক্টের শীর্ষে থাকে - আপনি অন্য প্রোগ্রামে স্যুইচ করলেও পপআপটি অন্য প্রোগ্রামের দৃশ্যমান এবং অস্পষ্ট অংশ হয়ে যাবে।
জেফ বি

ঠিক এই কারণেই আমি পপআপগুলি ব্যবহার করতে পছন্দ করি না .... কারণ তারা প্রোগ্রামটি সঙ্কুচিত করে না এবং তারা অন্যান্য সমস্ত প্রোগ্রামের শীর্ষে থাকে। এছাড়াও, প্রধান অ্যাপ্লিকেশনটির আকার পরিবর্তন / সরানো ডিফল্টরূপে এটির সাথে পপআপ সরান না।
রাচেল

এফডাব্লুআইডাব্লু, এই ইউআই কনভেনশনটি যাইহোক জঞ্জাল । টুলটিপ যা কিছু পড়তে গিয়ে অদৃশ্য হয়ে যায় তার চেয়ে কম কিছু জিনিস বিরক্তিকর।
রোমান স্টারকভ

7

আপনি আপনার যে শুধুমাত্র নির্দিষ্ট উপাদানের নির্দিষ্ট করতে চান Windowকার্যকরভাবে অনির্দিষ্ট আছে ToolTipসময়কাল আপনি একটি বর্ণনা করতে পারেন Styleআপনার Window.Resourcesসেই উপাদানের জন্য। এখানে একটি করা হয় Styleজন্য Buttonযে এই ধরনের হয়েছে ToolTip:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    ...>
    ...
    <Window.Resources>
        <Style x:Key="ButtonToolTipIndefinate" TargetType="{x:Type Button}">
            <Setter Property="ToolTipService.ShowDuration"
                    Value="{x:Static Member=sys:Int32.MaxValue}"/>
        </Style>
        ...
    </Window.Resources>
    ...
    <Button Style="{DynamicResource ButtonToolTipIndefinate}"
            ToolTip="This should stay open"/>
    <Button ToolTip="This Should disappear after the default time.">
    ...

এটির উপস্থিতিগুলির পরিবর্তনের Style.Resourcesজন্য কেউ এটিকে যুক্ত করতে Styleপারে ToolTip, উদাহরণস্বরূপ:

<Style x:Key="ButtonToolTipTransparentIndefinate" TargetType="{x:Type Button}">
    <Style.Resources>
        <Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="HasDropShadow" Value="False"/>
        </Style>
    </Style.Resources>
    <Setter Property="ToolTipService.ShowDuration"
            Value="{x:Static Member=sys:Int32.MaxValue}"/>
</Style>

নোট: আমি যখন আমি ব্যবহার করেনি BasedOnমধ্যে Styleঅন্য সব কিছুর একটি স্বাভাবিক সঙ্গে আমার কাস্টম নিয়ন্ত্রণ সংস্করণের জন্য নির্ধারিত তাই ToolTipপ্রয়োগ করা হবে।


5

আমি কেবল অন্য দিন ডব্লিউপিএফ টুলটিপ দিয়ে কুস্তি করেছিলাম। এটি নিজেকে উপস্থিত হওয়া এবং অদৃশ্য হয়ে যাওয়া থেকে থামানো সম্ভব বলে মনে হচ্ছে না, তাই শেষ পর্যন্ত আমি Openedইভেন্টটি পরিচালনা করার উপায় অবলম্বন করেছি । উদাহরণস্বরূপ, এটিতে কিছু সামগ্রী না থাকলে আমি এটিকে খোলার থেকে থামাতে চেয়েছিলাম, তাই আমি Openedইভেন্টটি পরিচালনা করেছি এবং পরে এটি করেছি:

tooltip.IsOpen = (tooltip.Content != null);

এটি একটি হ্যাক, কিন্তু এটি কাজ করে।

সম্ভবত আপনি একইভাবে Closedইভেন্টটি পরিচালনা করতে পারেন এবং এটিকে আবার খোলার জন্য বলতে পারবেন, যাতে এটি দৃশ্যমান থাকে।


টুলটিপটির হাসসন্টেন্ট নামে একটি সম্পত্তি রয়েছে যা আপনি তার পরিবর্তে ব্যবহার করতে পারেন
বেনপায়ার্স


0

এছাড়াও আপনি যদি কখনও নিজের টুলটিপটিতে অন্য কোনও নিয়ন্ত্রণ রাখতে চান তবে কোনও সরঞ্জামদ্বয় নিজেই ফোকাস পেতে পারে বলে এটি মনোনিবেশযোগ্য হবে না। মাইকাটন যেমনটি বলেছে, আপনার সেরা শট একটি পপআপ।


0

আমার ইস্যুটি একই কোড দিয়ে স্থির হয়েছে।

ToolTipService.ShowDistanceProperty.OverrideMetadata (typof (DependencyObject), নতুন ফ্রেমওয়ার্কপ্রপার্টিমেটাটাটা (ইন্টার 32.ম্যাক্সভ্যালু));


-4
ToolTipService.ShowDurationProperty.OverrideMetadata(
    typeof(DependencyObject), new FrameworkPropertyMetadata(Int32.MaxValue));

এটা আমার জন্য কাজ করছে। আপনার শ্রেণি নির্মাতায় এই লাইনটি অনুলিপি করুন।


3
এটি দ্বিতীয় সর্বাধিক প্রচারের সাথে স্বীকৃত উত্তরের অনুলিপি এবং পেস্ট করুন
কোডিংইউরলাইফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.