我有一个WPF应用程序。
在左侧有一个堆满了按钮的堆叠面板。
在右侧有一个空的停靠区。
当用户点击按钮时,会将相应的UserControl (查看)加载到停靠栏中:
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类,它从模型中获取信息,因此用户可以在页面之间点击,每个页面都可以携带隔离功能,例如编辑所有客户,保存到数据库等等。
但是,现在,在其中一个页面上,我想要一个ListBox,其中包含Customers列表,每个客户都有一个“编辑”按钮,当单击该编辑按钮时,我想填充DockPanel使用EditSingleCustomer UserControl并将其传递给需要编辑的客户。
我可以加载EditCustomer用户控件,但是如何将客户编辑并设置其DataContext以编辑该客户?
<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错误。 所以我认为我会以错误的方式解决这个问题,必须有一些更简单的范例来简单地将命令从一个UserControl传递到WPF中的另一个UserControl (之后有人说“使用WPF命令” “,我已经在我的UserControl上使用命令,允许用户编辑所有客户,这工作正常,但我必须在我的视图后面的代码中处理它(而不是在我的viewmodel中),因为我需要父窗口上下文能够在完成保存后加载另一个用户控件:
<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中简单地将一个UserControl加载到DockPanel中,在UserControl中有一个带有命令的按钮,它加载另一个UserControl,向UserControl发送一个它可以绑定的特定对象它的控制?
我可以想象我此时对WPF命令知之甚少,如果有人能从这里指出正确的方向,那就太好了,或者如果你认为这个“在DockPanel模式中加载UserControls是外来的对WPF应该避免并用另一种构建应用程序的方式替换“,这也是有用的新闻。您可以download the current state of my application here了解其结构。感谢。
答案 0 :(得分:3)
这是您使用Mediator模式的地方。关于此主题有几篇博客文章(针对instance),并且在某些WPF框架中有模式的实现(例如EventAggregator中的Prism)。
答案 1 :(得分:3)
我刚刚使用WPF完成了一个LOB应用程序,这种问题/模式经常出现,所以这就是我如何解决你的问题:
1)在DataTemplate中,在ListBox中创建每个项目及其编辑按钮,将Button的tag属性绑定到该列表框项下面的Customer对象。
2)为按钮创建Click事件处理程序,并设置Button的Click事件以触发处理程序。
3)在事件处理程序中,设置UserControl的Content属性。
4)在用户控件的范围内设置一个DataTemplate(可能在它的直接容器的资源中),它描述了该单个客户的编辑器。
另一种方法是在EditCustomer类上声明Customer依赖项属性,然后在单击该按钮时设置该属性(可能通过XAML Trigger)。
我希望这不是太模糊。如果没有别的,请知道你所遇到的问题在WPF中是可以解决的。
答案 2 :(得分:1)
我没有时间真正深入研究这个问题(这是一个有趣的问题,我希望你得到一个好的答案 - 我可以看到自己在未来遇到类似的情况。)
您是否考虑过少一点WPF-y并回退到使用包含客户的EventArgs在您的源UserControl上触发事件,然后在事件处理程序中,在目标控件上触发相应的命令?