2

我有一个带有 TextBox (Y) 和一个 Button 的用户控件,在我的 MainWindow(Y) 中还有另一个 TextBox。当您按下按钮时,会弹出一条消息并向我们显示产品 X*Y。

现在,如果我只是简单地通过 XAML 插入另一个,因为它绑定到 UserControl 的某些数据,原始和刚刚添加的显示相同(因为正如我所说的 TextBox.Text 已绑定)。

我想知道如何扩展它并在我的 MainWindow 中添加几个 UserControl,这样我就可以在每个 UserControl 中键入不同的值,然后按下按钮,看看每个产品有多少。

在此处输入图像描述

RootViewMode.cs

public class RootViewModel : INotifyPropertyChanged
    {
        #region Implementation of INotifyPropertyChanged

        private double _x;
        private double _y;

        public double X
        {
            get { return _x; }
            set
            {
                _x = value;
                OnPropertyChanged("X");
            }
        }

        public double Y
        {
            get { return _y; }
            set
            {
                _y = value;
                OnPropertyChanged("Y");
            }
        }

        public double XY
        {
            get { return _x * _y; }
        }
    }

UserControl1.xaml

  <StackPanel>
            <Label Content="Y:" />
            <TextBox Text="{Binding Path=Y, UpdateSourceTrigger=PropertyChanged, FallbackValue=1}" Margin="5" />
            <Button Content="Press me" Click="OnButtonClick" />
        </StackPanel>

UserControl1.xaml.cs

private void OnButtonClick(object sender, RoutedEventArgs e)
    {
        var viewModel = (RootViewModel)DataContext;
        var resultMessage = string.Format("{0} * {1} = {2}", viewModel.X, viewModel.Y, viewModel.XY);

        MessageBox.Show(resultMessage, "X * Y");
    }

主窗口.xaml

 <StackPanel>
        <Label Content="X:" />
        <TextBox Text="{Binding Path=X, UpdateSourceTrigger=PropertyChanged}" Margin="5" Height="24" />
        <WpfApplication22:UserControl1  Margin="5" />
        <WpfApplication22:UserControl1  Margin="5" />
    </StackPanel>

当然,以这种方式插入 UserControl 我得到了不想要的结果。我怀疑我必须为每个 UserControl 创建一个新的 RootViemModel,但这必须动态完成。我不只想要 2 个 UserControl,而是想要一种生成它们的方法,可能使用一个显示“创建 UserControl!”的按钮。谢谢。

(感谢 Sevenate 帮助我编写代码)

4

1 回答 1

3

你需要一个ItemsControl

<Window x:Class="MiscSamples.UserControlItemsControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="UserControlItemsControl" Height="300" Width="300">
    <DockPanel>
        <StackPanel DockPanel.Dock="Top">
            <Label Content="X:"/>
            <TextBox Text="{Binding X}"/>
            <Button Content="Add User Control" Command="{Binding AddUserControlCommand}"/>
        </StackPanel>

        <ItemsControl ItemsSource="{Binding Children}">
            <ItemsControl.Template>
                <ControlTemplate>
                    <ScrollViewer CanContentScroll="True">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </ItemsControl.Template>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <!-- Here you can place your local:UserControl. I just thrown the UI elements -->
                    <GroupBox Header="User Control">
                        <StackPanel>
                            <Label Content="Y:"/>
                            <TextBox Text="{Binding Y}"/>
                            <Button Content="Press Me!" Command="{Binding PressMeCommand}"/>
                        </StackPanel>
                    </GroupBox>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DockPanel>
</Window>

代码背后:

public partial class UserControlItemsControl : Window
{
    public UserControlItemsControl()
    {
        InitializeComponent();
        DataContext = new RootViewModel();
    }
}

根视图模型:

public class RootViewModel: PropertyChangedBase
{
    private double _x;
    public double X
    {
        get { return _x; }
        set
        {
            _x = value;
            OnPropertyChanged("X");
        }
    }

    public ObservableCollection<UserControlViewModel> Children { get; set; }
    public Command AddUserControlCommand { get; set; }

    public RootViewModel()
    {
        Children = new ObservableCollection<UserControlViewModel>();
        AddUserControlCommand = new Command(AddUserControl);
    }

    private void AddUserControl()
    {
        var child = new UserControlViewModel();
        child.PressMeCommand = new Command(() => OnUserControlPressed(child));
        Children.Add(child);
    }

    private void OnUserControlPressed(UserControlViewModel item)
    {
        if (item != null)
        {
            var xy = X * item.Y;
            var resultMessage = string.Format("{0} * {1} = {2}", X, item.Y, xy);

            MessageBox.Show(resultMessage, "X * Y");    
        }
    }
}

用户控制视图模型:

public class UserControlViewModel:PropertyChangedBase
{
    private double _y;
    public double Y
    {
        get { return _y; }
        set
        {
            _y = value;
            OnPropertyChanged("Y");
        }
    }

    public Command PressMeCommand { get; set; }
}

命令类(为了避免在不属于它们的地方使用单击事件处理程序):

//Dead-simple implementation of ICommand
//Serves as an abstraction of Actions performed by the user via interaction with the UI (for instance, Button Click)
public class Command : ICommand
{
    public Action Action { get; set; }

    public void Execute(object parameter)
    {
        if (Action != null)
            Action();
    }

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

    private bool _isEnabled = true;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            _isEnabled = value;
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, EventArgs.Empty);
        }
    }

    public event EventHandler CanExecuteChanged;

    public Command(Action action)
    {
        Action = action;
    }
}

public class Command<T>: ICommand
{
    public Action<T> Action { get; set; }

    public void Execute(object parameter)
    {
        if (Action != null && parameter is T)
            Action((T)parameter);
    }

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

    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            _isEnabled = value;
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, EventArgs.Empty);
        }
    }

    public event EventHandler CanExecuteChanged;

    public Command(Action<T> action)
    {
        Action = action;
    }
}

结果:

在此处输入图像描述

于 2013-06-04T16:21:03.783 回答