0

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

当我在数据上下文中使用ViewModelLocator时,命令绑定不起作用,如果我将 ViewModel 绑定到ViewModel本身的数据上下文,它就会起作用!

我在这里想念什么?

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>
4

2 回答 2

2

用户控件的数据上下文是 aViewModelLocator并且按钮绑定到MoCoConnectCommand属性。但是该类ViewModelLocator没有属性MoCoConnectCommand

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

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

<UserControl.DataContext>
    <Binding Source="{StaticResource Locator}" Path="motionViewModel" />
</UserControl.DataContext>
于 2020-10-16T09:53:39.423 回答
0

如果您想了解这一点,请尝试避免使用外部库。他们只会让事情变得混乱。

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

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

Window w = new Window();
w.DataContext= new SomethingViewModel();
w.Show();

现在您可以在 Window.xaml 中从 SomethingViewModel 绑定到公共属性

你还需要什么:

- 在基类(ViewModelBase 或您想要的任何名称)中实现 INotifyPropertyChange,您可以继续继承需要刷新 UI 的视图模型和对象

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

编辑:如果您坚持使用 3rd 方库,其他答案应该可以解决您的问题

于 2020-10-16T10:02:08.763 回答