ViewModelLocator 未启动

ViewModelLocator not firing up

我最近一直在阅读有关 MVVM(和 MVVM Light)的内容,因此尝试在具有 2 个 ViewModel 的应用程序中实现。

当我在数据上下文中使用 ViewModelLocator 时,命令绑定不起作用,如果我将 ViewModel 绑定到 ViewModel[=25= 的数据上下文] 本身就有效!

我在这里错过了什么?

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        
        SimpleIoc.Default.Register<MotionViewModel>();
        SimpleIoc.Default.Register<LiveViewViewModel>();
    }

    public LiveViewViewModel liveViewViewModel
    {
        get
        {
            return ServiceLocator.Current.GetInstance<LiveViewViewModel>();
        }
    }

    public MotionViewModel motionViewModel
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MotionViewModel>();
        }
    }

    public static void Cleanup()
    {
        ClearLiveViewViewModel();
        ClearMotionViewModel();
    }

    public static void ClearLiveViewViewModel()
    {
        ServiceLocator.Current.GetInstance<LiveViewViewModel>().CloseCamera();
        ServiceLocator.Current.GetInstance<LiveViewViewModel>().Cleanup();
    }

    public static void ClearMotionViewModel()
    {
        ServiceLocator.Current.GetInstance<MotionViewModel>().Cleanup();
    }
}

这是 ViewModel 代码:

public class MotionViewModel : ViewModelBase
{
    private RelayCommand _mocoConnectCommand;
    
    public MotionViewModel()
    {
        if (IsInDesignMode)
        {
            // Code runs in Blend --> create design time data.
        }
        else
        {
            // Code runs "for real"
            Task.Factory.StartNew(() => Initialize());
        }
    }
   
    public RelayCommand MoCoConnectCommand
    {
        get;
        private set;
    }
   
    private void Initialize()
    {
        MoCoConnectCommand = new RelayCommand(MoCoConnect);
    }

    private void MoCoConnect()
    {
        MessageBox.Show("Connection button pressed");
    }
    #endregion
}

这是XAML查看代码:

<UserControl.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator x:Key="Locator"/>
    </ResourceDictionary>
</UserControl.Resources>

<UserControl.DataContext>
    <Binding Source="{StaticResource Locator}" />
</UserControl.DataContext>

<Button Style="{DynamicResource MahApps.Metro.Styles.MetroButton}" 
            Grid.Column="0" Grid.Row="0"
            Height="30" Width="28" Margin="-1,2,1.333,2.667"
            Command="{Binding MoCoConnectCommand}" >
        <iconPacks:FontAwesome Kind="LinkSolid"/>
</Button>

用户控件的数据上下文是 ViewModelLocator,按钮绑定到 MoCoConnectCommand 属性。但是 class ViewModelLocator 没有 属性 MoCoConnectCommand.

我认为您需要在用户控件的数据上下文中注入 MotionViewModel,例如:

<UserControl.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator x:Key="Locator"/>
    </ResourceDictionary>
</UserControl.Resources>

<UserControl.DataContext>
    <Binding Source="{StaticResource Locator}" Path="motionViewModel" />
</UserControl.DataContext>

如果你想参与其中,请尽量避免使用外部库。他们只会让事情变得混乱。

需要了解的是,当您编写 SomeProperty="{Binding PropertyFromViewModel}" 时,它会绑定到该用户控件的 DataContext。 如何设置数据上下文? 简单示例:

将此(您的文件名替换示例文件名)写入您的 App.xaml.cs(覆盖 onstartup 方法)并从 App.xaml

中删除“StartupUri”
Window w = new Window();
w.DataContext= new SomethingViewModel();
w.Show();

现在您可以从 Window.xaml

中的 SomethingViewModel 绑定到 public 属性

您还需要什么:

-在基础 class(ViewModelBase 或您想要的任何名称)中实现 INotifyPropertyChange,您可以继续继承需要刷新 UI

的视图模型和对象

-RelayCommand 的实现。这可用于在任何视图模型中创建命令,这些视图模型可以通过绑定绑定到控件的命令,例如按钮。

编辑:如果您坚持使用第 3 方库,另一个答案应该可以解决您的问题