C# 使用自己的数据的用户控件
我有一个带有文本框(Y)和按钮的用户控件,在我的主窗口(Y)中有另一个文本框。当您按下按钮时,会弹出一条消息,向我们显示产品X*Y 现在,如果我只是简单地通过XAML插入另一个,因为它绑定到一些数据,包括UserControl,原始的和刚刚添加的显示相同(因为正如我所说的TextBox.Text是绑定的) 我想知道的是如何扩展它,在主窗口中添加几个UserControl,这样我就可以在每个UserControl中键入不同的值,然后按下按钮,查看每个产品的价格 RootViewMode.csC# 使用自己的数据的用户控件,c#,wpf,binding,user-controls,C#,Wpf,Binding,User Controls,我有一个带有文本框(Y)和按钮的用户控件,在我的主窗口(Y)中有另一个文本框。当您按下按钮时,会弹出一条消息,向我们显示产品X*Y 现在,如果我只是简单地通过XAML插入另一个,因为它绑定到一些数据,包括UserControl,原始的和刚刚添加的显示相同(因为正如我所说的TextBox.Text是绑定的) 我想知道的是如何扩展它,在主窗口中添加几个UserControl,这样我就可以在每个UserControl中键入不同的值,然后按下按钮,查看每个产品的价格 RootViewMode.cs p
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;
公共命令(行动)
{
行动=行动;
}
}
结果:
您需要一个
项控件和一个适当的数据项。我只想再次感谢您,您不知道您帮了我多少忙。现在我可以开始基于这个设计构建我的程序了。