问题是您不能直接绑定到Grid 的Children 集合,因为它不是DependencyProperty。您必须实现附加属性或行为才能这样做。但是,您可以将 ContentControl 放入您的 Grid 或将其替换为解决方法。然后将其Content 绑定到视图模型中的activeUserControl 属性。通常属性以大写字母开头,所以我对其进行了调整。
<Grid x:Name="ContentPanel" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5,5,5,5">
<ContentControl Content="{Binding ActiveUserControl}"/>
</Grid>
确保您的MainVM 在任何父控件中设置为DataContext,否则此绑定将不起作用。 activeUserControl 必须是一个属性才能使其可绑定。在您的MainVM 中实现INotifyPropertyChanged,以便ContentControl 在属性更改并适应其Content 时得到通知。
// Implement "INotifyPropertyChanged" so controls get notified about property changes
public class MainVM : INotifyPropertyChanged
{
// Backing field of the "ActiveUserControl" property
private UserControl _activeUserControl;
public UserControl ActiveUserControl
{
get => _activeUserControl;
set
{
// Only set the value if it has changed
if (_activeUserControl != value)
{
_activeUserControl = value;
// Signal to the control that it needs to update the value
OnPropertyChanged(nameof(ActiveUserControl));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public MainVM()
{
// ...your code.
ActiveUserControl = stability;
// ...your code.
}
protected virtual void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
这应该可以解决您的问题,但您的代码仍然是 MVVM 和代码隐藏的混合体。理想情况下,视图模型中不应有任何 UI 控件引用。
考虑使用INotifyPropertyChanged 和data templates 创建Tank 和Stability 视图模型来显示它们,而不是在视图模型中使用UserControls。在这种情况下,您仍然可以使用ContentControl。
<ContentControl Content="{Binding activeUserControl}">
<ContentControl.Resources>
<DataTemplate DataType={x:Type TankViewModel}>
<!-- ...data template equivalent of your "Tank" user control. -->
</DataTemplate>
<DataTemplate DataType={x:Type StabilityViewModel}>
<!-- ...data template equivalent of your "Stability" user control. -->
</DataTemplate>
</ContentControl.Resources>
</ContentControl>