从用户控件获取值

Get a value from a user control

我有一个带按钮的用户控件。单击按钮时创建一个随机数。我想在 Main Window 中使用这个号码。我在 Main Window 中使用了 3 次用户控件。但我无法在 main window 中获取号码。我使用 MVVM。 请帮帮我!

UserControl.xaml

    <UserControl x:Class="test.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:test"
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="300">
    <Grid>
        <Grid.DataContext>
            <local:UserControl1VM/>
        </Grid.DataContext>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="{Binding Path=txt}"/>
        <Button Grid.Column="1" Content="Show Num" Command="{Binding Path=AddNum}"/>
    </Grid>
</UserControl>

用户控制视图模型

public class UserControl1VM : INotifyPropertyChanged
{
    private string _txt;

    public string txt
    {
        get { return _txt; }
        set
        {
            _txt = value;
            OnPropertyChanged("txt");
        }
    }
    public RelayCommand AddNum { get; set; }


    public UserControl1VM()
    {
        AddNum = new RelayCommand(DoAddNum);
    }

    private void DoAddNum(object obj)
    {
        Random random = new Random();
        txt = random.Next(0, 100).ToString();
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

MainWindow.xaml

<Window x:Class="test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:test"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<UniformGrid Rows="4">
    <local:UserControl1 Margin="20"/>
    <local:UserControl1 Margin="20"/>
    <local:UserControl1 Margin="20"/>
    <UniformGrid Columns="2" Margin="20">
        <TextBlock Text="{Binding Path=Sum}"/>
        <Button Content="Sum" Command="{Binding Path=AddSum}"/>
    </UniformGrid>
</UniformGrid>

主要 Window 查看模型

public class MainWindowVM : INotifyPropertyChanged
{
    private string _Sum;

    public string Sum
    {
        get { return _Sum; }
        set
        {
            _Sum = value;
            OnPropertyChanged("Sum");
        }
    }

    public RelayCommand AddSum { get; set; }

    public MainWindowVM()
    {
        AddSum = new RelayCommand(DoAddSum);
    }


    private void DoAddSum(object obj)
    {

    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

RelayCommand.cs

public class RelayCommand : ICommand
{
    private string v;

    private Action<object> MyAction { get; set; }
    public RelayCommand(Action<object> MyAction)
    {
        this.MyAction = MyAction;
    }

    public RelayCommand(string v)
    {
        this.v = v;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        MyAction(parameter);
    }
}

我想要当点击 "Sum" 时在文本块中显示 3 个数字的总和。

我的建议

  • 将 'sum' 和 'txt' 属性 类型更改为 int - 总结数字更容易;-)

  • 在您的 ViewModel 上使用复合模式。让 MainWindow 视图模型由三个 UserControlVM 组成。

变化

1.) 更改为 MainWindow.xaml

<UniformGrid Rows="4">
    <UniformGrid.DataContext>
        <local:MainWindowVM/>
    </UniformGrid.DataContext>
    <local:UserControl1 Margin="20" DataContext="{Binding UserControlVM1}"/>
    <local:UserControl1 Margin="20" DataContext="{Binding UserControlVM2}"/>
    <local:UserControl1 Margin="20" DataContext="{Binding UserControlVM3}"/>

2.) 从 UserControl1.xaml 中移除:

<Grid.DataContext>
        <local:UserControl1VM/>
</Grid.DataContext>

3.) 改变MainWindowVM.cs

    public class MainWindowVM : INotifyPropertyChanged
{
    private readonly List<UserControl1VM> childVms;

    public UserControl1VM UserControlVM1 { get; set; }
    public UserControl1VM UserControlVM2 { get; set; }
    public UserControl1VM UserControlVM3 { get; set; }

    public MainWindowVM()
    {
        childVms = new List<UserControl1VM>()
        {
            new UserControl1VM(),
            new UserControl1VM(),
            new UserControl1VM(),
        };

        UserControlVM1 = childVms[0];
        UserControlVM2 = childVms[1];
        UserControlVM3 = childVms[2];

        AddSum = new RelayCommand(DoAddSum);
    }

    private int _Sum;


    public int Sum
    {
        get { return _Sum; }
        set
        {
            _Sum = value;
            OnPropertyChanged("Sum");
        }
    }

    public RelayCommand AddSum { get; set; }


    private void DoAddSum(object obj)
    {
        childVms.ForEach(vm => Sum += vm.txt);
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}