在呈现/实例化View时通知ViewModel

我有一个自定义usercontrol( ChartControl ),我在我的WPF应用程序( MainApp )中使用,我呈现如下:

  

启动MainApp后, MainApp给定顺序执行以下操作:

MainApp查看MainApp ViewModel ChartControl ViewModel ChartControl视图

我从ChartControl ViewModel的构造函数中实例化MainApp ViewModel。 问题是在实例化ChartControl ViewModel后,我还需要从MainApp调用ChartControl的方法。

我遇到的问题是,在调用方法作为其viewmodel的一部分之前,我需要渲染ChartControl视图(执行其InitializeComponent )。

我认为一个解决方案可能是在完全实例化和设置时从视图中通知视图模型。 这是一个可行的解决方案,如果是,我该怎么做?

总之,我需要在调用匹配的viewmodel的方法之前完全设置视图。 我遇到的问题是,在这种情况下,视图模型首先被实例化,然后才会呈现视图。

有任何想法吗?

谢谢

您可以使用Interactivity触发器在任何UI事件上触发VM上的Command

您可以像下面一样监听UserControl的Loaded事件,并将其绑定到VM上的Command:

       

确保你的VM中有Command

 public ICommand OnLoadedCommand { get; private set; } public MyUserControl() { OnLoadedCommand = new DelegateCommand(OnLoaded); } public void OnLoaded() { } 

连接Loaded事件的另一种方法,基本上呈现与nit的答案相同的结果,只是在视图的构造函数中引用您的viewmodel并添加一个事件处理程序,该处理程序又调用您需要调用的任何方法,如下所示:

 public MyControl() { InitializeComponent(); this.Loaded += (s, e) => { ((MyViewModel)DataContext).MyInitializer(); }; } 

如果您发现语法混乱,您可能需要阅读匿名方法和订阅事件处理程序(使用匿名方法) 。

我正在使用像Hogler这样的类似解决方案,只有reflection(懒惰耦合解决方案)。 我不想引用我的ViewModel的特定类型(因为通用性,可互换性等)。

 public MyControl() { InitializeComponent(); Loaded += MyControl_Loaded; } private void MyControl_Loaded(object sender, RoutedEventArgs e) { (DataContext.GetType().GetProperty("LoadedCommand")?. GetValue(DataContext) as ICommand)?. Execute(null); } 

ViewModel可以(不必)包含所需的命令,如属性(在本例中为LoadedCommand)。 而已。

在MVVM世界中,我发现在创建可视项目并将其放到视图上时(在这种情况下添加到列表中),在加载的事件被触发之前,该项目不会在可视树中。

我的视图模型包含XAML视图将显示的可观察集合中的项列表。

 ObservableCollection Items; 

我将一个项目添加到列表中,但是当我执行一项操作,要求它在可视化树中并执行可视树递归时,这不会立即发生。 相反,我必须编写这样的代码:

 var newItem = new MyControl(); newItem.Loaded += NewItemLoaded; Items.Add(new MyControl()); 

然后事件处理程序将取消挂钩并执行操作 – 此时根据需要位于可视化树中:

 private void NewItemLoaded(object sender, RoutedEventArgs e) { var item = sender as MyControl; item.Loaded -= NewItemLoaded; // now this item is in the visual tree, go ahead and do stuff ... }