2

in order to blink taskbar, I found the following code: https://stackoverflow.com/a/5118285/1830639, which give me 2 extensions methods that I care about:

window.FlashWindow(5);
window.StopFlashingWindow();

I'm creating some sort of chat messenger, and there are two interesting scenarios:

  1. Focus opened window when user clicks to chat an already opened chat.
  2. Blink opened window when a message arrives to an already opened chat.

The 1. I've accomplish with the following (https://stackoverflow.com/a/14765848/1830639):

 public class MetroWindowManager : WindowManager
{
    private IDictionary<WeakReference, WeakReference> windows = new Dictionary<WeakReference, WeakReference>();

    public override void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null)
    {
        NavigationWindow navWindow = null;

        if (Application.Current != null && Application.Current.MainWindow != null)
        {
            navWindow = Application.Current.MainWindow as NavigationWindow;
        }

        if (navWindow != null)
        {
            var window = CreatePage(rootModel, context, settings);
            navWindow.Navigate(window);
        }
        else
        {
            var window = GetExistingWindow(rootModel);
            if (window == null)
            {
                window = CreateWindow(rootModel, false, context, settings);
                windows.Add(new WeakReference(rootModel), new WeakReference(window));
                window.Show();
            }
            else
            {
                window.Focus();
            }
        }

    }

ChatManager:

 public class ChatManager : IChatManager
{
    private readonly IChatWindowSettings chatWindowSettings;
    private readonly IWindowManager windowManager;
    private IDictionary<WeakReference, WeakReference> chats;

    public ChatManager(IChatWindowSettings chatWindowSettings, IWindowManager windowManager)
    {
        this.chatWindowSettings = chatWindowSettings;
        this.windowManager = windowManager;

        chats = new Dictionary<WeakReference, WeakReference>();
    }

    public void OpenFor(Contact contact)
    {
        var settings = chatWindowSettings.Create();
        var viewModel = CreateOrGetViewModel(contact);
        windowManager.ShowWindow(viewModel, null, settings);
    }

    private ChatViewModel CreateOrGetViewModel(Contact contact)
    {
        ChatViewModel viewModel;
        if (!chats.Any(c => c.Key.IsAlive && c.Key.Target == contact))
        {
            viewModel = new ChatViewModel(contact);
            chats.Add(new WeakReference(contact), new WeakReference(viewModel));
        }
        else
        {
            var chat = chats.Single(d => d.Key.Target == contact).Value;
            if (!chat.IsAlive)
            {
                viewModel = new ChatViewModel(contact);
                chats.Add(new WeakReference(contact), new WeakReference(viewModel));
            }
            else
            {
                viewModel = chat.Target as ChatViewModel;
            }
        }

        return viewModel;
    }

As you can see, I'm relying on IWindowManager interface. Now for the 2. I thought of implementing an extension method on IWindowManager Blink(), however in the extension method I don't have access to the WeakReferences (windows variable) I've created in the MetroWindowManager:

 public void MessageFor(Contact contact, IChatMessage message)
    {
        var viewModel = CreateOrGetViewModel(contact);
        windowManager.Blink(viewModel);
    }

Any ideas?

Community
  • 1
  • 1
JobaDiniz
  • 862
  • 1
  • 14
  • 32

1 Answers1

0

I've figured it out. Going to share the code in case somebody is interested.

I've created my own IWindowManager that extends Caliburn.Micro.IWindowManager. The catch was how to get the same instance for both interfaces:

/// <summary>
/// Extends Caliburn.Micro.IWindowManager functionalities, such as blinking windows.
/// </summary>
public interface IWindowManager : Caliburn.Micro.IWindowManager
{
    void Blink(object rootModel);
}

MetroWindowManager:

public class MetroWindowManager : WindowManager, Communicator.Core.IWindowManager
{
    private IDictionary<WeakReference, WeakReference> windows = new Dictionary<WeakReference, WeakReference>();

    public void Blink(object rootModel)
    {
        //have access to 'windows' dictionary
    }

SimpleInjector Bootstrapper:

var windowManager = new MetroWindowManager();
        container = new Container();
        container.Register<Communicator.Core.IWindowManager>(()=> windowManager);
        container.Register<Caliburn.Micro.IWindowManager>(() => windowManager);

Whenever I have a dependency on my IWindowManager or Caliburn.Micro.IWindowManager, IoC passes the same instance.

JobaDiniz
  • 862
  • 1
  • 14
  • 32