2010-06-14 11 views
58

के साथ पॉपअप "टोस्टर" अधिसूचनाएं बनाएं। मैं .NET का उपयोग कर रहा हूं और एक डेस्कटॉप ऐप/सेवा बना रहा हूं जो कुछ ईवेंट ट्रिगर होने पर मेरे डेस्कटॉप के कोने में नोटिफिकेशन प्रदर्शित करेगा। मैं एक नियमित संदेश बॉक्स बी/सी का उपयोग नहीं करना चाहता जो बहुत घुसपैठ कर रहा हो। मैं अधिसूचनाओं को देखने में स्लाइड करना चाहता हूं और फिर कुछ सेकंड के बाद फीका हूं। मैं ऐसा कुछ सोच रहा हूं जो आउटलुक अलर्ट की तरह बहुत अधिक कार्य करेगा कि जब कोई नया संदेश आता है तो उसे प्राप्त होता है। सवाल यह है: क्या मुझे इसके लिए डब्ल्यूपीएफ का उपयोग करना चाहिए? मैंने WPF के साथ कभी भी कुछ नहीं किया है, लेकिन अगर यह अंत तक सबसे अच्छा साधन है तो खुशी से इसका प्रयास करेंगे। नियमित .NET पुस्तकालयों के साथ इसे पूरा करने का कोई तरीका है?विंडोज़ में .NET

+1

मुझे लगता है कि किसी भी तरह यह नियमित रूप से नेट के साथ संभव है, Infragistics यह करने के लिए कामयाब रहे: http://www.infragistics.com/dotnet/netadvantage/winforms/windesktopalert.aspx#Overview –

+1

हाँ, यही वही है जो मेरा मतलब था। लोग, कृपया अपने विचार साझा करें। मैं केवल सामान्य दिशा की तलाश में हूं, विस्तृत विवरण नहीं। धन्यवाद। – Antony

+0

यहां एक ऐसा है जो थोड़ी देर के लिए कोडप्रोजेक्ट पर रहा है। http://www.codeproject.com/KB/miscctrl/taskbarnotifier.aspx में 5 दिन से कम समय लगेगा। – quimbo

उत्तर

102

डब्ल्यूपीएफ यह बिल्कुल मामूली बनाता है: यह संभवतः दस मिनट या उससे कम समय लेगा। ये कदम उठाएँ:

  1. एक खिड़की, सेट AllowsTransparency = "true" बना सकते हैं और यह करने के लिए एक ग्रिड को जोड़ने
  2. सेट की 0,1
  3. मूल के साथ एक ScaleTransform को ग्रिड के RenderTransform पर एक एनीमेशन बनाएं ग्रिड जो स्केलएक्स 0 से 1 को एनिमेट करता है, उसके बाद ओपेसिटी को 1 से 0
  4. में बनाता है कन्स्ट्रक्टर में विंडो की गणना करें। विंडो और विंडो। स्क्रीन के निचले दाएं कोने में विंडो को स्थानांतरित करने के लिए।

यह सब कुछ है।

अभिव्यक्ति का उपयोग करते हुए ब्लेंड इसके बारे में 8 मिनट लग गए मुझे अगले कार्य कोड उत्पन्न करने के लिए:

<Window 
    x:Class="NotificationWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Notification Popup" Width="300" SizeToContent="Height" 
    WindowStyle="None" AllowsTransparency="True" Background="Transparent"> 

    <Grid RenderTransformOrigin="0,1" > 

    <!-- Notification area --> 
    <Border BorderThickness="1" Background="Beige" BorderBrush="Black" CornerRadius="10"> 
     <StackPanel Margin="20"> 
     <TextBlock TextWrapping="Wrap" Margin="5"> 
      <Bold>Notification data</Bold><LineBreak /><LineBreak /> 
      Something just happened and you are being notified of it. 
     </TextBlock> 
     <CheckBox Content="Checkable" Margin="5 5 0 5" /> 
     <Button Content="Clickable" HorizontalAlignment="Center" /> 
     </StackPanel> 
    </Border> 

    <!-- Animation --> 
    <Grid.Triggers> 
     <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
     <BeginStoryboard> 
      <Storyboard> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"> 
       <SplineDoubleKeyFrame KeyTime="0:0:0" Value="0"/> 
       <SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/> 
      </DoubleAnimationUsingKeyFrames> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"> 
       <SplineDoubleKeyFrame KeyTime="0:0:2" Value="1"/> 
       <SplineDoubleKeyFrame KeyTime="0:0:4" Value="0"/> 
      </DoubleAnimationUsingKeyFrames> 
      </Storyboard> 
     </BeginStoryboard> 
     </EventTrigger> 
    </Grid.Triggers> 

    <Grid.RenderTransform> 
     <ScaleTransform ScaleY="1" /> 
    </Grid.RenderTransform> 

    </Grid> 

</Window> 

पीछे कोड के साथ:

using System; 
using System.Windows; 
using System.Windows.Threading; 

public partial class NotificationWindow 
{ 
    public NotificationWindow() 
    { 
    InitializeComponent(); 

    Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => 
    { 
     var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea; 
     var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice; 
     var corner = transform.Transform(new Point(workingArea.Right, workingArea.Bottom)); 

     this.Left = corner.X - this.ActualWidth - 100; 
     this.Top = corner.Y - this.ActualHeight; 
    })); 
    } 
} 

WPF के बाद से नियमित रूप से नेट पुस्तकालयों में से एक है, जवाब हाँ है, यह "नियमित .NET पुस्तकालयों" के साथ इसे पूरा करने के लिए संभव है।

यदि आप पूछ रहे हैं कि WPF का उपयोग किए बिना ऐसा करने का कोई तरीका है तो उत्तर अभी भी हाँ है, लेकिन यह बेहद जटिल है और इसमें 5 मिनट से अधिक 5 दिन लगेंगे।

+0

यह बहुत अच्छा है। एक जादू की तरह काम करता है। धन्यवाद! प्रभावशाली यह कितना छोटा कोड लिया। – Antony

+0

+ कूल, आपने मुझे कुछ समय बचा लिया है! धन्यवाद) –

+17

यह सुनिश्चित नहीं है कि इसकी आवश्यकता है, लेकिन मैंने अस्पष्टता एनीमेशन में एक पूर्ण कार्यक्रम जोड़ा, और मैंने पीछे दिए गए कोड में "यह। बंद करें();"। अन्यथा खिड़की हमेशा खुली रहती है। आखिरी विंडो बंद होने के आधार पर बंद हो सकता है कि एक ऐप गड़बड़ कर सकते हैं। – Paul

0

ध्यान दें कि बुला धागा, क्योंकि कई UI घटक इस आवश्यकता स्टेशन जाना चाहिए लेखन का अनुसरण करते हुए system.timers.timer बीत घटना

Window1 notifyWin = new Window1(); 
bool? isOpen = notifyWin.ShowDialog(); 
if (isOpen != null && isOpen == true) 
{ 
    notifyWin.Close(); 
} 
System.Threading.Thread.Sleep(1000); 
notifyWin.ShowDialog(); 

तहत कोड window1 निर्माता के तहत:

public Window1() 
{ 
    InitializeComponent(); 

    Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => { 
     var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea; 
     var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice; 
     var corner = transform.Transform(new Point(workingArea.Right, workingArea.Bottom)); 
     this.Left = corner.X - this.ActualWidth - 100; 
     this.Top = corner.Y - this.ActualHeight; 
    })); 
} 
5
public partial class NotificationWindow : Window 
{ 
    DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer(); 
    public NotificationWindow() 
     : base() 
    { 
     this.InitializeComponent(); 

     Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => 
     { 
      var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea; 
      var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice; 
      var corner = transform.Transform(new Point(workingArea.Right, workingArea.Bottom)); 

      this.Left = corner.X - this.ActualWidth; 
      this.Top = corner.Y - this.ActualHeight; 
     })); 
     timer.Interval = TimeSpan.FromSeconds(4d); 
     timer.Tick += new EventHandler(timer_Tick); 
    } 
    public new void Show() 
    { 
     base.Show(); 
     timer.Start(); 
    } 

    void timer_Tick(object sender, EventArgs e) 
    { 
     //set default result if necessary 

     timer.Stop(); 
     this.Close(); 
    } 

} 

उपरोक्त कोड परिष्कृत संस्करण @ रे बर्न्स दृष्टिकोण है। समय अंतराल कोड के साथ जोड़ा गया। ताकि अधिसूचना खिड़की 4 सेकंड के बाद बंद कर देगा ..

कॉल के रूप में खिड़की,

NotificationWindow nfw = new NotificationWindow(); 
nfw.Show(); 
+0

अहहायन। । – Gopichandar

+0

@ गोपीचंदर मैं गोपी –

16

मैं आगे चला गया और कहा कि "टोस्ट पॉपअप" और नियंत्रण "सहायता गुब्बारे" भी शामिल है इस के लिए एक CodePlex साइट बनाई । इन संस्करणों में नीचे वर्णित की तुलना में अधिक सुविधाएं हैं। https://toastspopuphelpballoon.codeplex.com

यह उस समाधान के लिए एक शानदार कूद बिंदु था जिसे मैं ढूंढ रहा था।मैंने अपनी आवश्यकताओं को पूरा करने के लिए कुछ संशोधन किए हैं:

  • मैं माउस पर एनीमेशन को रोकना चाहता था।
  • माउस छोड़ने पर एनीमेशन "रीसेट करें"।
  • खिड़की जब अस्पष्टता पर पहुंच बंद 0.
  • ढेर टोस्ट (मैं समस्या हल नहीं किया है, तो खिड़कियों की संख्या स्क्रीन ऊंचाई से अधिक है) मेरी ViewModel

से

  • कॉल लोड यहाँ मेरी है XAML

    <Window x:Class="Foundation.FundRaising.DataRequest.Windows.NotificationWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="NotificationWindow" Height="70" Width="300" ShowInTaskbar="False" 
        WindowStyle="None" AllowsTransparency="True" 
        Background="Transparent"> 
    
    <Grid RenderTransformOrigin="0,1" > 
        <Border BorderThickness="2" Background="{StaticResource GradientBackground}" BorderBrush="DarkGray" CornerRadius="7"> 
         <Grid> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="60"/> 
           <ColumnDefinition Width="*"/> 
           <ColumnDefinition Width="24"/> 
          </Grid.ColumnDefinitions> 
    
          <Grid.RowDefinitions> 
           <RowDefinition Height="30"/> 
           <RowDefinition Height="*"/> 
          </Grid.RowDefinitions> 
    
          <Image Grid.Column="0" 
            Grid.RowSpan="2" 
            Source="Resources/data_information.png" 
            Width="40" Height="40" 
            VerticalAlignment="Center" 
            HorizontalAlignment="Center"/> 
    
          <Image Grid.Column="2" 
            Source="Resources/error20.png" 
            Width="20" 
            Height="20" 
            VerticalAlignment="Center" 
            ToolTip="Close" 
            HorizontalAlignment="Center" 
            Cursor="Hand" MouseUp="ImageMouseUp"/> 
    
          <TextBlock Grid.Column="1" 
             Grid.Row="0" 
             VerticalAlignment="Center" 
             HorizontalAlignment="Center" 
             FontWeight="Bold" FontSize="15" 
             Text="A Request has been Added"/> 
    
          <Button Grid.Column="1" 
            Grid.Row="1" 
            FontSize="15" 
            Margin="0,-3,0,0" 
            HorizontalAlignment="Center" 
            VerticalAlignment="Center" 
            Content="Click Here to View" 
            Style="{StaticResource LinkButton}"/> 
         </Grid>    
        </Border> 
    
        <!-- Animation --> 
        <Grid.Triggers> 
         <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
          <BeginStoryboard x:Name="StoryboardLoad"> 
           <Storyboard> 
            <DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="0.0" To="1.0" Duration="0:0:2" /> 
            <DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="1.0" To="0.0" Duration="0:0:8" BeginTime="0:0:5" Completed="DoubleAnimationCompleted"/> 
           </Storyboard> 
          </BeginStoryboard> 
         </EventTrigger> 
    
         <EventTrigger RoutedEvent="Mouse.MouseEnter"> 
          <EventTrigger.Actions> 
           <RemoveStoryboard BeginStoryboardName="StoryboardLoad"/> 
           <RemoveStoryboard BeginStoryboardName="StoryboardFade"/> 
          </EventTrigger.Actions> 
         </EventTrigger> 
    
         <EventTrigger RoutedEvent="Mouse.MouseLeave"> 
          <BeginStoryboard x:Name="StoryboardFade"> 
           <Storyboard> 
            <DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="1.0" To="0.0" Duration="0:0:8" BeginTime="0:0:2" Completed="DoubleAnimationCompleted"/> 
           </Storyboard> 
          </BeginStoryboard> 
         </EventTrigger> 
    
        </Grid.Triggers> 
    
        <Grid.RenderTransform> 
         <ScaleTransform ScaleY="1" /> 
        </Grid.RenderTransform> 
    </Grid> 
    

    कोड

    012,351,641 के पीछे
    public partial class NotificationWindow : Window 
    { 
        public NotificationWindow() 
         : base() 
        { 
         this.InitializeComponent(); 
         this.Closed += this.NotificationWindowClosed; 
        } 
    
        public new void Show() 
        { 
         this.Topmost = true; 
         base.Show(); 
    
         this.Owner = System.Windows.Application.Current.MainWindow; 
         this.Closed += this.NotificationWindowClosed; 
         var workingArea = Screen.PrimaryScreen.WorkingArea; 
    
         this.Left = workingArea.Right - this.ActualWidth; 
         double top = workingArea.Bottom - this.ActualHeight; 
    
         foreach (Window window in System.Windows.Application.Current.Windows) 
         {     
          string windowName = window.GetType().Name; 
    
          if (windowName.Equals("NotificationWindow") && window != this) 
          { 
           window.Topmost = true; 
           top = window.Top - window.ActualHeight; 
          } 
         } 
    
         this.Top = top; 
        } 
        private void ImageMouseUp(object sender, 
         System.Windows.Input.MouseButtonEventArgs e) 
        { 
         this.Close(); 
        } 
    
        private void DoubleAnimationCompleted(object sender, EventArgs e) 
        { 
         if (!this.IsMouseOver) 
         { 
          this.Close(); 
         } 
        } 
    } 
    

    ViewModel से कॉल:

    private void ShowNotificationExecute() 
        { 
         App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
          () => 
          { 
           var notify = new NotificationWindow(); 
           notify.Show(); 
          })); 
        } 
    

    शैलियाँ XAML में संदर्भित:

     <Style x:Key="LinkButton" TargetType="Button"> 
         <Setter Property="Template"> 
          <Setter.Value> 
           <ControlTemplate TargetType="Button"> 
            <TextBlock> 
             <ContentPresenter /> 
            </TextBlock> 
           </ControlTemplate> 
          </Setter.Value> 
         </Setter> 
         <Setter Property="Foreground" Value="Blue"/> 
         <Setter Property="Cursor" Value="Hand"/> 
         <Style.Triggers> 
          <Trigger Property="IsMouseOver" Value="True"> 
           <Setter Property="ContentTemplate"> 
            <Setter.Value> 
             <DataTemplate> 
              <TextBlock TextDecorations="Underline" Text="{TemplateBinding Content}"/> 
             </DataTemplate> 
            </Setter.Value> 
           </Setter> 
          </Trigger> 
         </Style.Triggers> 
        </Style> 
    
        <LinearGradientBrush x:Key="GradientBackground" EndPoint="0.504,1.5" StartPoint="0.504,0.03"> 
         <GradientStop Color="#FFFDD5A7" Offset="0"/> 
         <GradientStop Color="#FFFCE79F" Offset="0.567"/> 
        </LinearGradientBrush> 
    

    अद्यतन: जब फार्म के लिए बंद कर दिया है मैं इस ईवेंट हैंडलर जोड़ा "ड्रॉप "अन्य खिड़कियां।

    private void NotificationWindowClosed(object sender, EventArgs e) 
        { 
         foreach (Window window in System.Windows.Application.Current.Windows) 
         { 
          string windowName = window.GetType().Name; 
    
          if (windowName.Equals("NotificationWindow") && window != this) 
          { 
           // Adjust any windows that were above this one to drop down 
           if (window.Top < this.Top) 
           { 
            window.Top = window.Top + this.ActualHeight; 
           } 
          } 
         } 
        } 
    
  • +1

    समझ नहीं पाया अधिसूचनाविंडोक्लोज्ड काम कैसे करता है? यह कोड – HoKy22

    +0

    में कहीं और संदर्भित नहीं है इसके बारे में क्षमा करें। मैंने लापता कोड जोड़ा है। यह एक काम प्रगति पर रहा है, और मुझे अंतिम अपडेट में याद आया। – LawMan

    +0

    पूरी तरह से काम करता है! क्या आप अन्य घटनाओं को "ड्रॉप" करने के लिए बंद होने पर इस ईवेंट हैंडलर को जोड़ते हुए अर्थ के बारे में कुछ और बता सकते हैं। " आपका मतलब क्या है "ड्रॉप"? – HoKy22

    2
    NotifyIcon notifyIcon = new NotifyIcon(); 
    Stream iconStream = System.Windows.Application.GetResourceStream(new Uri("pack://application:,,,/Assets/ic_instant_note_tray.ico")).Stream; 
    notifyIcon.Icon = new System.Drawing.Icon(iconStream); 
    notifyIcon.Text = string.Format(Properties.Resources.InstantNoteAppName, Constants.Application_Name); 
    notifyIcon.Visible = true; 
    notifyIcon.ShowBalloonTip(5000, "tooltiptitle", "tipMessage", ToolTipIcon.Info); 
    notifyIcon.Visible = false; 
    notifyIcon.Dispose(); 
    
    संबंधित मुद्दे