WPF MVVM - 将UserControls上的属性绑定到容器的ViewModel

时间:2010-12-09 19:12:02

标签: wpf mvvm binding

我有一个Window(MainWindow.xaml),它有一个ViewModel(MainWindowViewModel.cs)。我还有一个名为MyUserControl.xaml的UserControl,它也有一个相应的ViewModel(MyUserControlViewModel.cs)。

我已将UserControl的两个实例插入MainWindow:

<Window x:Class="MyProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyProject"
    Title="My Window">
    <Grid>
        <local:MyUserControl Visibility="{Binding Path=MyUserControl1Visibility, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
        <local:MyUserControl Visibility="{Binding Path=MyUserControl2Visibility, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
    </Grid>
</Window>

在MainWindow的CodeBehind中,我将Window的DataContext设置为ViewModel的一个实例:

public MainWindow()
{
    InitializeComponent();
    this.DataContext = new MainWindowViewModel();
}

MainWindowViewModel具有MyUserControl实例绑定的Visibility属性。它们看起来都像这样:

private Visibility _myUserControl1Visibility = Visibility.Collapsed;
public Visibility MyUserControl1Visibility
{
    get
    {
        return _myUserControl1Visibility;
    }
    private set
    {
        if (value != _myUserControl1Visibility)
        {
            _myUserControl1Visibility = value;
            OnPropertyChanged("MyUserControl1Visibility");
        }
    }
}

此外,MainWindow和MainWindowViewModel具有按钮和命令,使用户能够在两个MyUserControl实例之间切换。也就是说,任何时候都只显示其中一个。

这很好用......直到UserControls获得了自己的ViewModels。现在,运行时尝试在UserControls的ViewModel上找到绑定的VisibilityProperties(MyUserControl1Visibility ...),而不是MainWindow的ViewModel。

如何将这些绑定转到MainWindowViewModel而不是UserControl实例的相应ViewModel?

2 个答案:

答案 0 :(得分:11)

MyUserControls从MainWindow继承了DataContext,这就是它开始工作的原因。当MyUserControl1获得自己的ViewModel时,它将是它的DataContext。也许你很清楚:)要在绑定中使用MainWindow的DataContext,你可以使用RelativeSource或命名Window并使用ElementName

<local:MyUserControl Visibility="{Binding ElementName=mainWindow, 
                                          Path=DataContext.MyUserControl1Visibility,
                                          Mode=OneWay,
                                          UpdateSourceTrigger=PropertyChanged}" />

答案 1 :(得分:0)

Visibility="{Binding RelativeSource={x:Static RelativeSource.Self},
            Path=DataContext.MyUserControl1Visibility}"