5

我正在尝试在 MVVM 项目中实现通知图标( http://www.hardcodet.net/projects/wpf-notifyicon )。我了解此控件旨在用于常规 WPF 项目。

我想知道如何实现气球功能(气球功能)。如本教程中所述,需要调用方法“ShowBallonTip”

//show balloon with built-in icon
  MyNotifyIcon.ShowBalloonTip(title, text, BalloonIcon.Error);

我能想到的唯一可以调用此方法的地方是在后面的代码中。我在后面的视图代码中有一点代码没有问题(即使我不想有任何代码),但我不知道如何让视图模型与视图对话并要求它调用这个方法。

即使我将此方法放在一个事件中,我如何以编程方式从视图模型中引发此事件?

知道我怎么能做到这一点吗?

4

4 回答 4

4

我已经能够通过初始化视图模型中的图标而不是 XAML 来显示气球提示。

只需在我的命令中调用 ShowBalloonTip 方法就可以了。

我为通知图标创建了一个包装器:NotifyService:

public class NotifyService : INotifyService
{
    private TaskbarIcon icon = new TaskbarIcon
        {
            Name = "NotifyIcon",
            Icon =
                new System.Drawing.Icon(
                    Application.GetResourceStream(Utils.FileUtils.MakeUri("/Icons/email.ico")).Stream),
        };


    public void Notify(string message)
    {

        icon.ShowBalloonTip("title", message, BalloonIcon.None);
    }

    public void ChangeIconSource(string path)
    {
        icon.Icon = new System.Drawing.Icon(
                    Application.GetResourceStream(Utils.FileUtils.MakeUri(path)).Stream);
    }
}

我在我的视图模型中使用了它:viewmodel

public class MainWindowViewModel : WindowViewModelBase
{
    private readonly INotifyService notifyService = new NotifyService();

    #region Fields
    private static HomeWindowViewModel homeViewModel = new HomeWindowViewModel();
    #endregion
    /// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.
    /// </summary>
    public MainWindowViewModel()
        : base()
    {
        CurrentViewModel = homeViewModel;
    }

    #region Methods

    protected override void OnViewModelPropertyChanged(IViewModel viewModel, string propertyName)
    {
        int t = 2;
    }

    protected override void OnViewModelCommandExecuted(IViewModel viewModel, ICatelCommand command, object commandParameter)
    {
        int t = 2;
        notifyService.ChangeIconSource(@"/Icons/new_email.ico");
        notifyService.Notify("test");
    }
    #endregion
}
于 2012-09-20T16:19:21.610 回答
4

我找到了一个不太明显的解决方案,但可以说更适合 MVVM 模式。它允许在 XAML 中创建 TaskbarIcon 并由 ViewModel 提供新的气球数据。

首先要做的是添加某种功能来通知 TaskbarIcon 我们希望它显示一个气泡我选择使用 Microsofts Rx Extensions (NuGet Package Rx-Main) 来实现此目的,但任何合适的基础设施都可以工作。这是新的 TaskbarIcon 类,并且是一个用于保存我们希望在调用 ShowBubbleTip 方法时传递的数据的类。

using Hardcodet.Wpf.TaskbarNotification;
using System;
using System.Windows;
namespace Phi.Utility
{
    public class TaskbarIconRxBallonNotification
    {
        public Hardcodet.Wpf.TaskbarNotification.BalloonIcon Icon
        {
            get;
            private set;
        }
        public string BallonTitle
        {
            get;
            private set;
        }
        public string Message
        {
            get;
            private set;
        }
        public TaskbarIconRxBallonNotification(Hardcodet.Wpf.TaskbarNotification.BalloonIcon icon, string balloonTitle, string message)
        {
            Icon = icon;
            BallonTitle = balloonTitle;
            Message = message;
        }
    }
    public class TaskbarIconRx : TaskbarIcon
    {
        public IObservable<TaskbarIconRxBallonNotification> BalloonTipNotifier
        {
            get { return (IObservable<TaskbarIconRxBallonNotification>)GetValue(BallonTipNotifierProperty); }
            set { SetValue(BallonTipNotifierProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BalloonSubject.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BallonTipNotifierProperty =
            DependencyProperty.Register("BalloonTipNotifier", typeof(IObservable<TaskbarIconRxBallonNotification>), typeof(TaskbarIconRx), new PropertyMetadata(null, BallonTipNotifierChanged));

        //What to do when we get a new ballonIcon request
        protected void OnNextNotification(TaskbarIconRxBallonNotification notification)
        {
            ShowBalloonTip("", notification.Message, BalloonIcon.Info);
        }
        private IDisposable _subscription;

        //Make sure swapping out bindings doesn't break our program.
        public static void BallonTipNotifierChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TaskbarIconRx currentNotifier = d as TaskbarIconRx;
            if (currentNotifier != null)
            {
                IObservable<TaskbarIconRxBallonNotification> prev = e.OldValue as IObservable<TaskbarIconRxBallonNotification>;
                IObservable<TaskbarIconRxBallonNotification> next = e.NewValue as IObservable<TaskbarIconRxBallonNotification>;

                if (currentNotifier._subscription != null)
                {
                    currentNotifier._subscription.Dispose();
                    currentNotifier._subscription = null;
                }
                if ((next != null))
                {

                    currentNotifier._subscription = next.Subscribe(currentNotifier.OnNextNotification);
                }
            }
        }

    }
}

在我们的模型中,我们提供了一个 ISubject 来绑定

using System.Reactive.Subjects;
namespace Phi.Models {
    public class SomeModel:ModelBase {
        public ISubject<Utility.TaskbarIconRxBallonNotification> NotifierInterface
        {
            get;
            private set;
        }
        public SomeModel() {
            NotifierInterface = new Subject<Utility.TaskbarIconRxBallonNotification>();

        }
    }
}

在我们的 ViewModel 中,我们现在可以通过模型主题推送通知,如下所示:

namespace Phi.ViewModels{
    public class SomeViewModel:ViewModelBase
    {
        public SomeModel Model{
            get;
            private set;
        }
        public void PushNotification(string message)
        {
            //Pushes a new notification to the TaskbarIcon.
            Model.NotifierInterface.OnNext(new Utility.TaskbarIconRxBallonNotification(Hardcodet.Wpf.TaskbarNotification.BalloonIcon.Info, "Title", message));
        }
    }
}

在 XAML 中,我们绑定到我们的模型 ISubject

<Utility:TaskbarIconRx Visibility= IconSource="/Resources/TinyLogo.ico" BalloonTipNotifier="{Binding Model.NotifierInterface}" >
于 2015-04-27T20:36:41.637 回答
1

只需在视图中使用 ContentControl 绑定到在 VM 中实例化的 TaskbarIcon 对象。然后直接向 VM 中的对象发出命令。

XAML:

     <ContentControl Content="{Binding NotifyIcon}"/>

代码:

    private TaskbarIcon notifyIcon;
    public TaskbarIcon NotifyIcon
    {
        get { return notifyIcon; }
        set { notifyIcon = value; OnPropertyChanged("NotifyIcon"); }
    }
    private void ShowBalloon()
    {
       NotifyIcon.ShowBalloonTip("Hi", "Some info here.", BalloonIcon.Info);
    }
于 2017-07-12T15:43:01.113 回答
0
TaskbarIcon MyNotifyIcon = new TaskbarIcon();

    private void ShowStandardBalloon()
    {

        if (ping == false)
        {
            string title = "Website is offline!";
            string text = Url;
            MyNotifyIcon.ShowBalloonTip(title, text, BalloonIcon.Error);
        }else if(ping == true)
        {
            string title = "Website is online!";
            string text = Url;
            MyNotifyIcon.ShowBalloonTip(title, text, BalloonIcon.Info);
        }
     }

将其粘贴到您的 ViewModel 中并更改值,您就可以开始了。只需调用 ShowStandartBallon(); 并且您在 Code Behind 中没有代码。

[编辑]

TaskbarIcon MyNotifyIcon = new TaskbarIcon();

    private void ShowStandardBalloon()
    {
            string title = "Website is offline!";
            string text = Url; //Url is a String
            MyNotifyIcon.ShowBalloonTip(title, text, BalloonIcon.Error);
    }
于 2016-08-08T11:37:37.767 回答