gpt4 book ai didi

c# - 如何动态地将控件添加到另一个类中的WrapPanel?

转载 作者:行者123 更新时间:2023-12-02 20:21:35 25 4
gpt4 key购买 nike

我正在从 VB 迁移到 C#,并认为 WPF 将是我的最佳选择,因为我一直在开发的程序是高度依赖于 GUI 的应用程序。然而,当我试图让 VB 中的简单任务在 C# 代码中工作时,C# 给我带来了很多头痛、困惑和沮丧。在 VB 中,我可以非常轻松地实现这一点。但在 C# 中,在花费了无数个小时(现在已经好几天)搜索和使用代码之后,我仍然不知道如何让它工作。

我的场景:

  • 我有 2 个 xaml 页面。
  • 第一个 xaml 页面有一个包装面板。
  • 第二个 xaml 页面有一个按钮,它将创建一个新按钮并将其添加到 xaml 页面 1 中的包装面板中。

在 page1.xaml.cs 中使用以下代码时,我可以轻松地将新按钮添加到包装面板:

Button New_Button = new Button();
My_WrapPanel.Children.Add(New_Button);

我还尝试从 page2 调用位于 page1 中的方法来创建按钮,但新按钮未显示在包装面板中!?

我真的很感谢一些帮助,可能还有一个简单的代码示例来帮助我。

最佳答案

好的,我使用 UserControl 而不是 Page 将它们保留在单个窗口中。由于您没有发布任何 XAML,我不知道您真正的需求是什么,但这是我的看法:

MultiPageSample.xaml(“主窗口”):

<Window x:Class="MiscSamples.MultiPageMVVM.MultiPageSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MiscSamples.MultiPageMVVM"
Title="MultiPageSample" Height="300" Width="300">
<UniformGrid Rows="1" Columns="2">
<local:Page1 DataContext="{Binding Page1}"/>
<local:Page2 DataContext="{Binding Page2}"/>
</UniformGrid>
</Window>

背后代码:

public partial class MultiPageSample : Window
{
public MultiPageSample()
{
InitializeComponent();

DataContext = new MultiPageViewModel();
}
}

View 模型:

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页:

<UserControl x:Class="MiscSamples.MultiPageMVVM.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ItemsControl ItemsSource="{Binding Commands}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding}" Content="Click Me!"
Margin="2"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>

背后代码:

public partial class Page1 : UserControl
{
public Page1()
{
InitializeComponent();
}
}

第2页:

<UserControl x:Class="MiscSamples.MultiPageMVVM.Page2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button Content="Add New Command (I Mean Button)"
VerticalAlignment="Center" HorizontalAlignment="Center"
Command="{Binding AddNewCommand}"/>
</UserControl>

背后代码:

public partial class Page2 : UserControl
{
public Page2()
{
InitializeComponent();
}
}

View 模型:

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<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;
}
}

结果:

enter image description here

现在,解释一下所有这些困惑的情况:

首先,您必须了解 leave behind the traditional mentality 在代码中操作 UI 元素,并拥抱 MVVM

WPF 具有非常强大的 DataBinding 功能,这在古代恐龙框架中是完全不存在的。

请注意我如何使用可重用的 Command 类(这是大多数 MVVM 框架的基本部分)来表示 Page1ViewModel 中的按钮。然后,这些 Command 实例被添加到 ObservableCollection 中,DataTemplate 又会在向其中添加或删除元素时通知 WPF,从而通过 Binding 自动更新 UI .

然后,定义为 Page1ItemTemplateItemsControl 用于“渲染”ObservableCollection 内的每个项目。

当我说 WPF 需要一种完全不同的思维方式来工作时,我指的就是这个。这是 WPF 中所有内容的默认方法。您几乎不需要在程序代码中引用/创建/操作 UI 元素。这就是 XAML 的用途。

还请注意,通过对两个 Page 使用相同的 ViewModel 可以大大简化这一点,但我故意将它们分开,只是为了向您展示这种情况您有不同的 ViewModel 直接相互通信。

如果您有任何疑问,请告诉我。

关于c# - 如何动态地将控件添加到另一个类中的WrapPanel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16366732/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com