ContentControl Content Property not changing with hosted content

自古美人都是妖i 提交于 2019-12-04 08:18:19

It's hard to be 100% sure without having your project to test with, but I am fairly confident that at least one of the issues is that your UserControl and your MainWindow use different instances of the MainWindowViewModel. You do not need to instantiate the VM for the user control, as it will inherit the DataContext from the MainWindow. The way it works in WPF is that if any given UIElement does not have theDataContext assigned explicitly, it will inherit it from the first element up the logical tree that does has one assigned.

So, just delete this code, and it should solve at least that issue.

<UserControl.DataContext>
    <viewmodels:MainWindowViewModel/>
</UserControl.DataContext>

And since you're learning WPF, I feel obligated to provide a couple other tips. Even though you're using a ViewModel, you are still mixing UI and logic by creating a very specific implementation of ICommand and assigning a UI element through your ViewModel. This breaks the MVVM pattern. I know MVVM takes a little time to understand, but once you do, it is very easy to use and maintain.

To solve your problem, I would suggest creating View Models for each of your user controls. Please see this answer, where I go into quite a bit of detail on the implementation.

For switching the different views, you have a couple of options. You can either use a TabControl, or if you want to use a command, you can have a single ContentControl bound to a property of MainWindowViewModel that is of type ViewModelBase. Let's call it CurrentViewModel. Then when the command fires, you assign the view model of the desired user control to that bound property. You will also need to utilize implicit data templates. The basic idea is that you create a template for each of the user control VM types, which would just contains an instance of the Views. When you assign the user control VM to the CurrentViewModel property, the binding will find those data templates and render the user control. For example:

<Window.Resources>
  <DataTemplate DataType = "{x:Type viewmodels:RecoveryOperationsViewModel}">
    <views:RecoveryOperationsView/>
  </DataTemplate> 
  <!-- Now add a template for each of the views-->
</Window.Resources>

<ContentControl x:Name="MainWindowContentControl" Content="{Binding CurrentViewModel}"/>

See how this approach keeps UI and logic at an arm's length?

And lastly, consider creating a very generic implementation of ICommand to use in all your ViewModels rather than many specific implementations. I think most WPF programmers have more or less this exact RelayCommand implementation in their arsenal.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!