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 方库,另一个答案应该可以解决您的问题
我最近一直在阅读有关 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 方库,另一个答案应该可以解决您的问题