C# 使用自己的数据的用户控件

C# 使用自己的数据的用户控件,c#,wpf,binding,user-controls,C#,Wpf,Binding,User Controls,我有一个带有文本框(Y)和按钮的用户控件,在我的主窗口(Y)中有另一个文本框。当您按下按钮时,会弹出一条消息,向我们显示产品X*Y 现在,如果我只是简单地通过XAML插入另一个,因为它绑定到一些数据,包括UserControl,原始的和刚刚添加的显示相同(因为正如我所说的TextBox.Text是绑定的) 我想知道的是如何扩展它,在主窗口中添加几个UserControl,这样我就可以在每个UserControl中键入不同的值,然后按下按钮,查看每个产品的价格 RootViewMode.cs p

我有一个带有文本框(Y)和按钮的用户控件,在我的主窗口(Y)中有另一个文本框。当您按下按钮时,会弹出一条消息,向我们显示产品X*Y

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

我想知道的是如何扩展它,在主窗口中添加几个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; }
        }
    }
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");
    }
UserControl1.xaml

  <StackPanel>
            <Label Content="Y:" />
            <TextBox Text="{Binding Path=Y, UpdateSourceTrigger=PropertyChanged, FallbackValue=1}" Margin="5" />
            <Button Content="Press me" Click="OnButtonClick" />
        </StackPanel>
 <StackPanel>
        <Label Content="X:" />
        <TextBox Text="{Binding Path=X, UpdateSourceTrigger=PropertyChanged}" Margin="5" Height="24" />
        <WpfApplication22:UserControl1  Margin="5" />
        <WpfApplication22:UserControl1  Margin="5" />
    </StackPanel>
main window.xaml

  <StackPanel>
            <Label Content="Y:" />
            <TextBox Text="{Binding Path=Y, UpdateSourceTrigger=PropertyChanged, FallbackValue=1}" Margin="5" />
            <Button Content="Press me" Click="OnButtonClick" />
        </StackPanel>
 <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,而是想要一种生成它们的方法,可能需要一个按钮,上面写着“createusercontrol!”。谢谢

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

您需要一个:

<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>
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; }
}
命令类(避免在不属于它们的地方使用单击事件处理程序):

//ICommand的简单实现
//作为用户通过与UI交互执行的操作的抽象(例如,按钮单击)
公共类命令:ICommand
{
公共操作动作{get;set;}
public void Execute(对象参数)
{
如果(操作!=null)
动作();
}
公共布尔CanExecute(对象参数)
{
返回被禁止;
}
private bool _isEnabled=true;
公共场所被禁止
{
获取{return}
设置
{
_isEnabled=值;
如果(CanExecuteChanged!=null)
CanExecuteChanged(此为EventArgs.Empty);
}
}
公共事件处理程序CanExecuteChanged;
公共命令(行动)
{
行动=行动;
}
}
公共类命令:ICommand
{
公共操作动作{get;set;}
public void Execute(对象参数)
{
if(Action!=null&&参数为T)
作用((T)参数);
}
公共布尔CanExecute(对象参数)
{
返回被禁止;
}
私人住宅已启用;
公共场所被禁止
{
获取{return}
设置
{
_isEnabled=值;
如果(CanExecuteChanged!=null)
CanExecuteChanged(此为EventArgs.Empty);
}
}
公共事件处理程序CanExecuteChanged;
公共命令(行动)
{
行动=行动;
}
}
结果:


您需要一个
项控件和一个适当的数据项。我只想再次感谢您,您不知道您帮了我多少忙。现在我可以开始基于这个设计构建我的程序了。