我有一个带有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");
}
MainWindow.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!”的Button。感谢。
(感谢sevenate帮我编写代码)
答案 0 :(得分: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();
}
}
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");
}
}
}
UserControlViewModel:
public class UserControlViewModel:PropertyChangedBase
{
private double _y;
public double Y
{
get { return _y; }
set
{
_y = value;
OnPropertyChanged("Y");
}
}
public Command PressMeCommand { get; set; }
}
命令类(为避免使用不属于的Click事件处理程序):
//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;
}
}
结果: