如何动态控件添加到另一个类WrapPanel中?控件、动态、WrapPanel

2023-09-03 04:14:27 作者:漫漫人生路、

我从VB迁移到C#和决定,因为我一直在开发的项目是高度依赖于GUI应用程序的WPF将是我最好的选择。然而,C#是试图得到什么是VB简单的任务,在C#code上班的时候害我许多烦恼,困惑和沮丧。在VB中,我能得到这个很容易的工作。但在C#中,花费了无数的时间(现在的天)搜索和code上场后,我仍然不更明智如何得到这个工作。

I'm migrating from VB to C# and decided that WPF would be the best option for me as the programs I've been developing are highly GUI dependant based applications. However, C# is causing me a lot of headaches, confusion, and frustration when trying to get what are simple tasks in VB to work in C# code. In VB, I can get this working VERY easily. But in C#, after spending countless hours (now days) searching and playing with code, I'm still non the wiser how to get this working.

我的情况:

在我有2 XAML页面。 在第一个XAML页面有一个WrapPanel中。 第二XAML页面有一个按钮,将创建一个新的按钮,并将其添加到XAML页面1 WrapPanel中。

我可以使用下面的code在page1.xaml.cs时轻松添加新的按钮WrapPanel中:

I can easily add a new button to the wrappanel when using the code below in page1.xaml.cs:

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

我也打过电话位于第1页第2页距离的方法来创建按钮,但新的按钮并不在WrapPanel中展现!?

I've also tried calling a method located in page1 from page2 to create the button but the new button does not show in the wrappanel !?

我真的AP preciate一些帮助,可能一个简单的code例子来帮助我对我的方式。

I would really appreciate some help and possibly a simple code example to help me on my way.

推荐答案

好吧,进出口使用用户控件的S代替 s到让他们在一个窗口。既然你没有张贴任何XAML,我不知道你真正需要的是什么,但这里是我的看法:

Ok, Im using UserControls instead of Pages to keep them in a single Window. Since you didn't post any XAML, I have no idea what your real need is, but here is my take:

MultiPageSample.xaml(主窗口):

MultiPageSample.xaml ("Main Window"):

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

code背后:

Code Behind:

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

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

code背后:

Code Behind:

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>

code背后:

Code Behind:

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

视图模型:

public class Page2ViewModel
{
    public Command AddNewCommand { get; set; }
}

Command类(可以在大多数MVVM框架中找到)

Command class (can be found on most MVVM frameworks)

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

结果:

现在,这一切混乱的解释:

Now, the explanation of all this mess:

首先,必须留下的的传统心态背后操纵在code UI元素的,拥抱MVVM.

First of all, you must leave behind the traditional mentality of Manipulating UI elements in code, and embrace MVVM.

WPF具有非常强大的数据绑定的能力,这在古代的恐龙框架完全缺席。

WPF has very powerful DataBinding capabilities that are utterly absent in ancient dinosaur frameworks.

请注意我使用的是可重复使用的命令类(这是一种最MVVM框架的基本组成部分),以重新present的按钮Page1ViewModel 。 命令的这些实例,然后添加到 的ObservableCollection ,这反过来又通知WPF当一个元素被添加或删除的微博,因此用户界面会自动被绑定。

Notice how I'm using the reusable Command class (which is kind of a basic part of most MVVM frameworks) to represent the Buttons in the Page1ViewModel. These instances of Command are then added to the ObservableCollection, which in turn notifies WPF when an element is added or removed to it, and thus the UI is automatically updated by the Binding.

随后, 的DataTemplate 定义为ItemTemplate为ItemsControl在是用来呈现内的所有项目的ObservableCollection

Then, the DataTemplate defined as the ItemTemplate for the ItemsControl in Page1 is used to "render" each item inside the ObservableCollection.

这就是我指的是,当我说WPF需要一个非常不同的心态与合作。这是默认的方法,一切都在上头。你几乎永远不会有需要引用/创建/操纵程序code UI元素。这就是XAML是。

This is what I refer to when I say WPF needs a really different mindset to work with. This is the default approach to EVERYTHING in WPF. You almost NEVER have the need to reference / create / manipulate UI elements in procedural code. That's what XAML is for.

另请注意,这可以通过使用相同的简化了很多视图模型 S,但我让他们分开的目的,只是为了告诉你这种情况下,你有不同的ViewModels直接相互通信。

Also notice that this could be simplified A LOT by using the same ViewModel for both Pages, but I kept them separate on purpose just to show you this case where you have different ViewModels communicating with each other directly.

让我知道,如果您有任何疑问。

Let me know if you have any doubts.