【问题标题】:WPF User Control nested control - switch Usercontrol from UsercontrolWPF用户控件嵌套控件-从用户控件切换用户控件
【发布时间】:2020-06-28 23:19:48
【问题描述】:

我目前正在使用 Visual Studio 中的 WPF 开发一个应用程序,作为 MySQL 数据库的前端,然后应该在学校中使用它来简化硬件等的组织。 我对 C# 和 WPF 完全陌生,因此现在遇到了我在过去几个小时内无法解决的问题。 UI 由一个带有导航栏等的窗口和一个用于显示当前用户控件的大框架/网格组成。

单击主窗口导航栏中的按钮会触发一个事件,然后只需使用以下几行即可毫无问题地切换 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

我不知道这是否真的是实现它的最佳方式(因为它总是重新加载 UserControl),但至少它简单且有效。

问题是,我只能通过主窗口类切换用户控件。但我希望能够从其中一个用户控件中切换用户控件。 (例如,我的一个 UserControls 显示了一个 dataGrid,其中包含我的一个 db 表中的所有数据。通过双击这些行之一,我希望能够将该表的当前 UserControl 切换到另一个。)

但我真的不知道该怎么做。我做了一些研究,但只找到了由几十个不同类和许多不同事件处理程序等组成的解决方案,不幸的是我无法真正弄清楚该实现是如何工作的。而且它也仅限于 2 个 UserControl。

有什么方法可以在合理的时间内实现吗?我读过可能可以通过使用路由事件来做到这一点?由于我是 C# 新手,所以我对事件、调度程序等完全陌生,因此很难处理所有基于事件的东西。 :D

谢谢:)

【问题讨论】:

    标签: c# wpf xaml user-interface user-controls


    【解决方案1】:

    一个简单的解决方案是使用数据绑定:

    MainWindow.xaml

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

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

    更高级的解决方案将涉及DataTemplate 和不同的视图模型或数据模型,特定类型将映射到特定控件。然后在添加模型时显示控件,例如到ContentPresenter,它会自动应用正确的DataTemplate,以便可视化模型数据。

    【讨论】:

    • 哦,哇,感谢您提供超级详细的回复 :)) 老实说,我仍然无法 100% 理解它,但问题是我仍然对 C# 特定语法不是很坚定(第一次使用 C#)。但我肯定会更深入地研究语法和您的解决方案,并尝试将其实施到我的项目中,因为这看起来确实很有希望。 :)) 谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2010-10-01
    相关资源
    最近更新 更多