How to call method in window (.xaml.cs) from viewmodel (.cs) without introducing new references in wpf How to call method in window (.xaml.cs) from viewmodel (.cs) without introducing new references in wpf wpf wpf

How to call method in window (.xaml.cs) from viewmodel (.cs) without introducing new references in wpf


VM should "know" nothing of your View or Window, the way VM typically "communicates" with V in WPF/MVVM is by rasing events. That way VM remains ignorant of/decoupled from the V and since VM is already DataContext of V it's not hard to subscribe to VM's event.

Example:

VM:

public event EventHandler<NotificationEventArgs<string>> DoSomething;...Notify(DoSomething, new NotificationEventArgs<string>("Message"));

V:

var vm = DataContext as SomeViewModel; //Get VM from view's DataContextif (vm == null) return; //Check if conversion succeededvm.DoSomething += DoSomething; // Subscribe to eventprivate void DoSomething(object sender, NotificationEventArgs<string> e){    // Code    }


first of all, it's not a stupid question. Most of MVVM starters came from winforms and it's normal to have the tendency to bring in your winforms practices and work on code behind. Now all you have to do is forget that and think MVVM.

Going back to your question, you have a dictionary that your VM is processing and you are accessing that dictionary from the view. Your view should not have any idea about your viewmodel except through binding.

Making a window flash when there are changes in the viewmodel sounds like an attached behavior to me. Here's a good read about attached behavior. http://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF

To make it easier, I'll try to give you a very simple example that will somehow be relevant to your case.

Create an attached behavior class where you have an IEnumerable where in whenever you add something a messagebox will appear on the screen. Just change the messagebox code to whatever flashing animation you would like to do on notify.

public class FlashNotificationBehavior{    public static readonly DependencyProperty FlashNotificationsProperty =        DependencyProperty.RegisterAttached(        "FlashNotifications",        typeof(IEnumerable),        typeof(FlashNotificationBehavior),        new UIPropertyMetadata(null, OnFlashNotificationsChange));    private static void OnFlashNotificationsChange(DependencyObject d, DependencyPropertyChangedEventArgs e)    {        var collection = e.NewValue as INotifyCollectionChanged;        collection.CollectionChanged += (sender, args) =>             {                if (args.Action == NotifyCollectionChangedAction.Add)                {                    foreach (var items in args.NewItems)                        MessageBox.Show(items.ToString());                }            };                }    public static IEnumerable GetFlashNotifications(DependencyObject d)    {        return (IEnumerable)d.GetValue(FlashNotificationsProperty);    }    public static void SetFlashNotifications(DependencyObject d, IEnumerable value)    {        d.SetValue(FlashNotificationsProperty, value);    }}

In your viewmodel, you can create an ObservableCollection property, you need an observable collection so there is a collection changed event notification. I also added a command for adding so that you can test it.

   public class MainViewModel : ViewModelBase{    ObservableCollection<string> notifications;    public ObservableCollection<string> Notifications    {        get { return notifications; }        set        {            if (notifications != value)            {                notifications = value;                base.RaisePropertyChanged(() => this.Notifications);            }        }    }    public ICommand AddCommand    {        get        {            return new RelayCommand(() => this.Notifications.Add("Hello World"));        }    }    public MainViewModel()    {        this.Notifications = new ObservableCollection<string>();                 }}

And here's a view where you can bind it the Notifications proeprty from your view model.

<Window x:Class="WpfApplication7.MainWindow"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:vm="clr-namespace:WpfApplication7.ViewModel"    xmlns:local="clr-namespace:WpfApplication7"    Title="MainWindow" Height="350" Width="525"><Window.DataContext>    <vm:MainViewModel /></Window.DataContext><Grid>    <StackPanel>        <ListBox ItemsSource="{Binding Notifications}"                  local:FlashNotificationBehavior.FlashNotifications="{Binding Notifications}"></ListBox>        <Button Command="{Binding AddCommand}" >Add Something</Button>    </StackPanel></Grid>

Everytime you add something in the ObservableCollection, you will get a messagebox notifying the user that something has been added to your collection.

I hope that I helped in your problem. Just tell me if you need some clarifications.