如何将信息从一个 WPF UserControl 传递到另一个 WPF UserControl? [英] How to pass information from one WPF UserControl to another WPF UserControl?

查看:31
本文介绍了如何将信息从一个 WPF UserControl 传递到另一个 WPF UserControl?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 WPF 应用程序.

I've got a WPF application.

左侧有一个堆满按钮的堆栈面板.

On the left side there is a stackpanel full of buttons.

右侧有一个空的停靠面板.

On the right side there is an empty dockpanel.

当用户点击按钮时,它将相应的用户控件(视图)加载到停靠面板中:

When user clicks a button, it loads the corresponding UserControl (View) into the dockpanel:

private void btnGeneralClick(object sender, System.Windows.RoutedEventArgs e)
{
    PanelMainContent.Children.Clear();
    Button button = (Button)e.OriginalSource;
    Type type = this.GetType();
    Assembly assembly = type.Assembly;

    IBaseView userControl = UserControls[button.Tag.ToString()] as IBaseView;
    userControl.SetDataContext();

    PanelMainContent.Children.Add(userControl as UserControl);
}

这种模式效果很好,因为每个 UserControl 都是一个 View,它有一个 ViewModel 类,该类提供它从模型中获取的信息,因此用户可以在页面之间单击,并且每个页面都可以携带删除孤立的功能,例如编辑所有客户、保存到数据库等.

This pattern works well since each UserControl is a View which has a ViewModel class which feeds it information which it gets from the Model, so the user can click from page to page and each page can carry out isolated functionality, such as editing all customers, saving to the database, etc.

但是,现在,在其中一个页面上,我想要一个包含客户列表的 ListBox,并且每个客户都有一个编辑"按钮,当单击该编辑按钮时,我想填充 DockPanel使用 EditSingleCustomer UserControl 并将其传递给它需要编辑的 Customer.

However, now, on one of these pages I want to have a ListBox with a list of Customers in it, and each customer has an "edit" button, and when that edit button is clicked, I want to fill the DockPanel with the EditSingleCustomer UserControl and pass it the Customer that it needs to edit.

我可以加载 EditCustomer 用户控件,但是我如何将它传递给客户进行编辑并设置其 DataContext 以编辑该客户?

I can load the EditCustomer usercontrol, but how do I pass it the customer to edit and set up its DataContext to edit that customer?

  • 我无法在构造函数中传递它,因为所有 UserControl 都已创建并存在于 MainWindow.xaml.cs 的字典中.
  • 所以我在每个 UserControl 上创建了一个 PrepareUserControl 方法并将 Customer 传递给它,并且可以使用 x:Name="..." 代码后面的文本框显示它,但这不是重点,我需要 DataBind 一个ItemsControl 到 ObservableCollection 当然可以利用 WPF 的数据绑定功能.
  • 所以我尝试将视图中的 ListBox ItemSource 绑定到其背后的代码,如下所示:
<UserControl.Resources>
    <local:ManageSingleCustomer x:Key="CustomersDataProvider"/>
</UserControl.Resources>

<DockPanel>
    <ListBox ItemsSource="{Binding Path=CurrentCustomersBeingEdited, Source={StaticResource CustomersDataProvider}}"
             ItemTemplate="{DynamicResource allCustomersDataTemplate}"
             Style="{DynamicResource allCustomersListBox}">
    </ListBox>
</DockPanel>

在该视图中的 IntializeComponent() 中因无限循环而导致 stackoverflow 错误.所以我认为我以错误的方式解决这个问题,必须有一些更简单的范例来简单地将命令从 WPF 中的一个 UserControl 传递到另一个 UserControl(并且在有人说使用 WPF 命令之前",我已经在我的 UserControl 上使用命令,它允许用户编辑所有客户,这很好用,但我必须在我的视图后面的代码中(而不是在我的视图模型中)处理它,因为我需要父窗口上下文完成保存后能够加载另一个用户控件:

which gets a stackoverflow error caused by an endless loop in the IntializeComponent() in that view. So I'm thinking I'm going about this in the wrong way, there must be some easier paradigm to simply pass commands from one UserControl to another UserControl in WPF (and before someone says "use WPF commanding", I already am using commanding on my UserControl that allows the user to edit all customers, which works fine, but I have to handle it in my code behind of my view (instead of in my viewmodel) since I need the parent window context to be able to load another user control when its finished saving:

<Button Style="{StaticResource formButton}" 
        Content="Save" 
        Command="local:Commands.SaveCustomer"
        CommandParameter="{Binding}"/>

private void OnSave(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
{
    Customer customer = e.Parameter as Customer;
    Customer.Save(customer);

    MainWindow parentShell = Window.GetWindow(this) as MainWindow;
    Button btnCustomers = parentShell.FindName("btnCustomers") as Button;
    btnCustomers.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
}

那么在 WPF 中,我如何可以简单地在 DockPanel 中加载一个 UserControl,在该 UserControl 内有一个带有命令的按钮,该按钮加载另一个 UserControl 并向该 UserControl 发送它可以绑定的特定对象它的控件?

我可以想象我目前对 WPF 命令的了解还不够,如果有人能从这里向我指出正确的方向,那就太好了,或者如果您认为在 DockPanel 模式中加载 UserControls 是陌生的"WPF,应该避免并用另一种构建应用程序的方式代替",这也是有用的消息.您可以在此处下载我的应用程序的当前状态以获取它的结构的想法.谢谢.

I can imagine I just do not know enough about WPF commands at this point, if anyone can point me in the right direction from here, that would be great, or if you think this "loading UserControls in a DockPanel pattern is foreign to WPF and should be avoided and replaced with another way to structure applications", that would be helpful news as well. You can download the current state of my application here to get an idea of how it is structured. Thanks.

推荐答案

我刚刚使用 WPF 完成了一个 LOB 应用程序,其中此类问题/模式不断出现,所以我将如何解决您的问题:

I've just finished a LOB application using WPF where this sort of problem/pattern appeared constantly, so here's how I would have solved your problem:

1) 在您创建 ListBox 中每个项目的 DataTemplate 中,连同它的编辑按钮,将 Button 的标签属性绑定到该列表框项目下面的 Customer 对象.

1) In the DataTemplate where you create each item in the ListBox, along with it's edit button, bind the Button's tag property to the Customer object underlying that list box item.

2) 为按钮创建一个 Click 事件处理程序,并设置按钮的 Click 事件以触发处理程序.

2) Create a Click event handler for the button, and set the Button's Click event to fire the handler.

3) 在事件处理程序中,设置 UserControl 的 Content 属性.

3) In the event handler, set the Content property of the UserControl.

4) 在用户控件范围内(可能在其直接容器的资源中)设置一个 DataTemplate,它描述了该单个客户的编辑器.

4) Set up a DataTemplate in scope of the User Control (perhaps in the resources of it's immediate container) which describes an editor for that single customer.

另一种可行的方法是在 EditCustomer 类上声明 Customer 依赖项属性,然后在单击按钮时设置该属性(可能通过 XAML 触发器).

Another approach that will work is to declare a Customer dependency property on your EditCustomer class, then set that property (perhaps through a XAML Trigger) when the button is clicked.

我希望这不是太模糊.如果不出意外,请知道您面临的问题在 WPF 中是可以解决的.

I hope this isn't too vague. If nothing else, know that the problem you're facing is very solvable in WPF.

这篇关于如何将信息从一个 WPF UserControl 传递到另一个 WPF UserControl?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆