简体   繁体   English

WPF 用户控件嵌套控件 - 从用户控件切换用户控件

[英]WPF User Control nested control - switch Usercontrol from Usercontrol

I'm currently developing an application with WPF in Visual Studio as a front-end for a MySQL database which is then supposed to be used in a school to make the organisation of hardware etc. a bit more easy.我目前正在 Visual Studio 中使用 WPF 开发一个应用程序,作为 MySQL 数据库的前端,然后应该在学校中使用它来使硬件等的组织更容易一些。 I'm totally new to C# and WPF and therefore now ran into an issue I was not able to solve in the last hours.我对 C# 和 WPF 完全陌生,因此现在遇到了一个我在过去几个小时内无法解决的问题。 The UI consists of a Window with a Navbar etc. and a big Frame/Grid which is used to display the current UserControl. UI 由一个带有导航栏等的窗口和一个用于显示当前用户控件的大框架/网格组成。

Clicking onto a Button in my Mainwindow's navbar does trigger an Event which then switches the UserControl without any problems simply with these lines:单击主窗口导航栏中的按钮确实会触发一个事件,然后只需使用以下几行即可切换 UserControl,而不会出现任何问题:

ContentFrame.Children.Clear();  //ContentFrame is a simple Grid which I am using ot display the UserControls
ContentFrame.Children.Add(new UserControlDashboard());  //UserControlDashboard is the Class of one of my UserControls

I do not know if this is really the best way to implement that (since it always reloads the UserControl), but at least it is simple and working.我不知道这是否真的是实现它的最佳方式(因为它总是重新加载 UserControl),但至少它很简单并且有效。

The problem is, that I am only able to Switch the UserControls via the Mainwindow Class.问题是,我只能通过 Mainwindow 类切换 UserControls。 But I want to be able to switch the UserControl from within one of the UserControls.但我希望能够从 UserControl 之一中切换 UserControl。 (Eg One of my UserControls shows a dataGrid with all the data from one of my db tables. By double clicking on one of these rows I want to be able to switch the current UserControl with that table to a different one.) (例如,我的一个 UserControl 显示了一个 dataGrid,其中包含来自我的一个 db 表的所有数据。通过双击这些行之一,我希望能够将带有该表的当前 UserControl 切换到另一个表。)

But I can't really figure out how I can do that.但我真的不知道我怎么能做到这一点。 I've done some research but only found solutions which consisted of douzens of different classes with lots of different Eventhandlers etc. and unfortunately I couldn't really figure out how that implementation worked.我做了一些研究,但只找到了解决方案,其中包含许多不同的类和许多不同的事件处理程序等。不幸的是,我无法真正弄清楚该实现是如何工作的。 And it was also limited to 2 UserControls.它也仅限于 2 个用户控件。

Is there any way I can implement that with a reasonable amount of time?有什么办法可以在合理的时间内实现它吗? I've read that it might be possible to do by using Routed Events?我读过使用路由事件可以做到吗? Since I'm new to C# I am totally new to events, dispatchers etc. and therefore have a hard time with all that event-based stuff.因为我是 C# 的新手,所以我对事件、调度程序等完全陌生,因此很难处理所有基于事件的东西。 :D :D

Thanks :)谢谢 :)

A simple solution would be to use data binding:一个简单的解决方案是使用数据绑定:

MainWindow.xaml主窗口.xaml

<Window>
  <StackPanel>
    <SwitchingControl x:Name="BindingSourceControl" />
    <ContentControl x:Name="ContentFrame" 
                    Content="{Binding ElementName=BindingSourceControl, Path=SelectedControl}" />
  </StackPanel>
</Window>

SwitchingControl.xaml.cs SwitchingControl.xaml.cs

partial class SwitchingControl : UserControl
{
  public static readonly DependencyProperty SelectedControlProperty = DependencyProperty.Register(
    "SelectedControl",
    typeof(Control),
    typeof(SwitchingControl),
    new PropertyMetadata(default(Control)));

  public Control SelectedControl
  {
    get => (Control) GetValue(SwitchingControl.SelectedControlProperty);
    set => SetValue(SwitchingControl.SelectedControlProperty, value);
  }

  // Dictionary to store reusable controls
  private Dictionary<string, Control> ControlMap { get; set; }

  public SwitchingControl()
  {
    this.ControlMap = new Dictionary<string, Control>() 
    { 
      { nameof(UserControlDashboard), new UserControlDashboard()) }
    };
  }

  // TODO::Invoke when a DataGrid row was double clicked
  private void OnNewControlSelected(string selectedControlKey)
  {
    if (this.ControlMap.TryGetValue(selectedControlKey, out Control selectedControl)
    {
      this.SelectedControl = selectedControl;
    }
  }
}

A more advanced solution would involve DataTemplate and different view models or data models, which specific type would map to a specific control.更高级的解决方案将涉及DataTemplate和不同的视图模型或数据模型,特定类型将映射到特定控件。 The control are then displayed, when a model is added eg to a ContentPresenter , which would automatically apply the correct DataTemplate in order to visualize the model data.然后显示控件,当模型添加到例如ContentPresenter ,它将自动应用正确的DataTemplate以可视化模型数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM