如何动态地将控件添加到另一个类的WrapPanel?
我正在从VB迁移到C#,并认为WPF对我来说是最好的选择,因为我一直在开发的程序是基于GUI的高度依赖的应用程序。 但是,在尝试获取VB中的简单任务以使用C#代码时,C#给我带来了很多麻烦,困惑和沮丧。 在VB中,我可以非常轻松地完成这项工作。 但是在C#中,在花了无数个小时(现在几天)搜索和玩代码之后,我仍然不知道如何让这个工作。
我的情景:
- 我有2个xaml页面。
- 第一个xaml页面有一个wrappanel。
- 第二个xaml页面有一个按钮,它将创建一个新按钮并将其添加到xaml第1页的wrappanel中。
在page1.xaml.cs中使用下面的代码时,我可以轻松地向wrappanel添加一个新按钮:
Button New_Button = new Button(); My_WrapPanel.Children.Add(New_Button);
我也试过调用第2页的page1中的方法来创建按钮,但新的按钮没有显示在wrappanel中!
我真的很感激一些帮助,可能还有一个简单的代码示例来帮助我。
好吧,我使用UserControl
而不是Page
来将它们保存在一个窗口中。 由于你没有发布任何XAML,我不知道你真正需要什么,但这是我的看法:
MultiPageSample.xaml(“主窗口”):
代码背后:
public partial class MultiPageSample : Window { public MultiPageSample() { InitializeComponent(); DataContext = new MultiPageViewModel(); } }
视图模型:
public class MultiPageViewModel { public Page1ViewModel Page1 { get; set; } public Page2ViewModel Page2 { get; set; } public MultiPageViewModel() { Page1 = new Page1ViewModel(); Page2 = new Page2ViewModel(); Page2.AddNewCommand = new Command(Page1.AddCommand); } }
第1页:
代码背后:
public partial class Page1 : UserControl { public Page1() { InitializeComponent(); } }
第2页:
代码背后:
public partial class Page2 : UserControl { public Page2() { InitializeComponent(); } }
视图模型:
public class Page2ViewModel { public Command AddNewCommand { get; set; } }
命令类(可以在大多数MVVM框架上找到)
//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: ICommand { public Action 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 action) { Action = action; } }
结果:
现在,解释所有这些混乱:
首先,您必须抛弃 在代码中操纵UI元素 的传统心态 ,并拥抱MVVM 。
WPF具有非常强大的DataBindingfunction,在古代恐龙框架中完全没有。
请注意我是如何使用可重用的Command
类(它是大多数MVVM框架的基本部分)来表示Page1ViewModel中的按钮。 然后将这些Command
实例添加到ObservableCollection
, ObservableCollection
会在向其添加或删除元素时通知WPF,因此Binding
会自动更新UI。
然后,定义为Page1
ItemsControl
的ItemTemplate
的DataTemplate
用于“渲染” ObservableCollection
每个项目。
当我说WPF需要一种非常不同的思维模式时,我就是这么说的。 这是WPF中一切的默认方法。 您几乎从不需要在过程代码中引用/创建/操作UI元素。 这就是XAML的用途。
另外请注意,这可以通过对两个Page
使用相同的ViewModel
来简化A LOT,但我故意将它们分开,只是为了向您展示这种情况,即您有不同的ViewModel直接相互通信。
如果您有任何疑问,请告诉我。