如何在viewmodel(.cs)中调用窗口(.xaml.cs)中的方法而不在wpf中引入新引用

16 c# wpf mvvm viewmodel

我正在寻找一种在我的主窗口中调用方法的简单方法,但我想从我的View Model中调用它.基本上,我正在寻找一些"this.parent"之类的东西放在View Model中引用主窗口.

或者,如果你想查看我想要这样做的原因并告诉我另一种解决我的问题的方法:

我正在使用一个不断获取信息的应用程序.在viewmodel中,处理信息.我想在每次提供满足一定资格的信息时发出通知.

最初,我在viewmodel中有一个字典存储了有关该信息的信息,我在MainWindow中访问了该字典,以便我可以使窗口闪烁并发送其他通知.但是当我在MainWindow中访问它时,我遇到了viewmodel字典不断变化的问题.

对不起,这个问题听起来很愚蠢.我刚刚在两个月前开始使用WPF,并且在此之前也没有很好的编程背景.

Dea*_*uga 31

VM应该"知道"您的视图或窗口,VM在WPF/MVVM中通常与V"通信"的方式是通过rasing事件.这样,VM仍然不知道/与V分离,因为VM已经DataContext是V,所以不容易订阅VM的事件.

例:

VM:

public event EventHandler<NotificationEventArgs<string>> DoSomething;
...
Notify(DoSomething, new NotificationEventArgs<string>("Message"));
Run Code Online (Sandbox Code Playgroud)

五:

var vm = DataContext as SomeViewModel; //Get VM from view's DataContext
if (vm == null) return; //Check if conversion succeeded
vm.DoSomething += DoSomething; // Subscribe to event

private void DoSomething(object sender, NotificationEventArgs<string> e)
{
    // Code    
}
Run Code Online (Sandbox Code Playgroud)


Lan*_*nce 13

首先,这不是一个愚蠢的问题.大多数MVVM初学者来自winforms,并且倾向于引入你的winforms实践并且在代码背后工作是正常的.现在你所要做的就是忘记并思考MVVM.

回到你的问题,你有一个你的虚拟机正在处理的字典,你正在从视图中访问该字典.除了通过绑定之外,您的视图不应该对您的viewmodel有任何了解.

在视图模型中发生更改时使窗口闪烁听起来像是对我的附加行为.这是关于附加行为的好读物. http://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF

为了方便起见,我将尝试给你一个非常简单的例子,它将以某种方式与你的案例相关.

创建一个附加的行为类,其中有一个IEnumerable,无论何时添加内容,屏幕上都会出现一个消息框.只需将消息框代码更改为您想要通知的任何闪烁动画.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的viewmodel中,您可以创建一个ObservableCollection属性,您需要一个可观察的集合,因此有一个集合已更改事件通知.我还添加了一个添加命令,以便您可以测试它.

   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>();             
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有一个视图,您可以从视图模型中将Notifications proeprty绑定到该视图.

<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>
Run Code Online (Sandbox Code Playgroud)

每次在ObservableCollection中添加内容时,您都会收到一个消息框,通知用户已将某些内容添加到您的集合中.

我希望我帮助解决你的问题.告诉我你是否需要澄清一下.