如何将命令和上下文从UserControl绑定到MainView UWP MVVM

问题描述

一个标签位于其中的表格,以及包装在按钮中的用户控件。我需要通过单击用户控件中的按钮来更改TextBlock中的文本。我没有使用任何MVVM框架。 主要XAML:

    <Page.DataContext>
    <local:Mainviewmodel />
</Page.DataContext>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.ColumnDeFinitions>
        <ColumnDeFinition Width="553*" />
        <ColumnDeFinition Width="197*" />
    </Grid.ColumnDeFinitions>
    <local:ControlView Grid.Column="1" HorizontalAlignment="Stretch"
                       VerticalAlignment="Stretch" />
    <TextBlock Grid.Column="0" Foreground="Black" FontSize="50" VerticalAlignment="Stretch"
               HorizontalAlignment="Stretch" Text="{Binding UserText,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
    
</Grid>

用户控制Xaml:

<Grid>
    <Button Width="300" Height="100" FontSize="50" Command="{Binding}"
            VerticalAlignment="Center" HorizontalAlignment="Center" Content="Print chart" />
</Grid>

主虚拟机:

 public class Mainviewmodel : INotifyPropertyChanged
{
    public Mainviewmodel()
    {
        
        SetText = new RelayCommand(SetUserText);
    }

    public ICommand SetText { get; set; }

    public string UserText { get; set; }

    
    public event PropertyChangedEventHandler PropertyChanged;

    private void SetUserText()
    {
        UserText = "Hello World!";
        RaisePropertyChanged(nameof(UserText ));
    }

    
    protected void RaisePropertyChanged(string property)
    {
        PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(property));
    }
}

然后我创建一个空的用户控件VN:

public class Controlviewmodel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string property)
    {
        PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(property));
    }

    // And what should I do here?
}

那么如何正确实现从用户控件到主视图的命令(例如SetText属性)?

解决方法

您的主要问题是ControlViewModel的使用。通常,UserControls之类的ControlView不应将自己的DataContext设置为某些专门的视图模型,而应从其父元素继承DataContext

假设您让控件继承了DataContext,则可以向其添加一个依赖项属性,并将命令绑​​定到该属性:

<local:ControlView YourCommand="{Binding SetText}" />

ControlView.xaml:

<UserControl ... Name="uc">
    <Button Command="{Binding YourCommand,ElementName=uc}" />