几天前我问this question,但是答案让我更加困惑。所以我会问一个更简单的问题:
(我正在使用Caliburn.Micro,这是一个WPF应用程序)。假设你有一个MainView / MainViewModel,它有AView / AViewModel和BView / BViewModel作为子项。您的MainView是一个网格,并且您希望使用AView或BView填充其中一个单元格,具体取决于用户选择。如果我只想展示AView,我会做以下事情:
在MainView中:
<StackPanel Name="SP_Controls" VerticalAlignment="Bottom" Grid.Row="1" Grid.Column="0">
<ContentControl Name="ViewModelToShow" Margin="10" />
</StackPanel>
并在MainViewModel中:
public AViewModel ViewModelToShow{get; set;}
我天真的想法现在就是做这样的事情:
private AViewModel _AVM;
private BViewModel _BVM;
public ... ViewModelToShow{ get; set;}
然后在代码中,例如,将viewmodel设置为show:
ViewModelToShow = _BVM;
我唯一的问题是“...”,因为每个ViewModel属于不同的类。有没有办法用泛型来做这个,或者我应该为我的ViewModel定义一个基类?但是,如果我这样做,他们仍然会正确显示。谢谢。
答案 0 :(得分:6)
您查看的模型应该继承自PropertyChangedBase
或Screen
。 Screen
继承自PropertyChangedBase
,并且还实现了IScreen
。 Screen
增加了生命周期(即OnActivate
等)。
然后你可以使用你的方法,即拥有一个名为eg的公共财产。 CurrentViewModel
IScreen
类型CurrentViewModel
。然后,您可以在需要时将其设置为适当的视图模型。请注意,如果您希望正确更新UI,则此NotifyOfPropertyChange
属性应在引用更改时调用setter中的Conductor
。
或者,您可以将父视图模型视为两个子视图模型的指导,并使用内置的Caliburn.Micro Conductor<IScreen>.Collection.OneActive
类型。例如,派生自Items
。
然后,您可以将2个子视图模型添加到父级ActivateItem
集合中,并调用ContentControl
方法来设置当前视图模型。然后将视图x:Name
更新为ActiveItem
{{1}}。
有关详细信息,请参阅here。
答案 1 :(得分:1)
以上所有答案都是正确的。就视图位置的工作方式而言,属性类型无关紧要。只有实例的运行时类型很重要。因此,您甚至可以将属性定义为对象类型,它仍然可以工作。只需确保您的财产提出更改通知即可。对于Conductor,ActiveItem会为您处理。
答案 2 :(得分:1)
我通常从ViewModelBase类继承。它是一个包含所有属性更改位和bobs的类。但由于视图上的DataContext属性只是一个对象,因此类型并不重要。