WPF 用户控件嵌套控件 - 从 Usercontrol 切换 Usercontrol
WPF User Control nested control - switch Usercontrol from Usercontrol
我目前正在 Visual Studio 中使用 WPF 开发一个应用程序作为 MySQL 数据库的前端,然后应该在学校中使用它来组织硬件等.更容易一点。
我是 C# 和 WPF 的新手,因此现在 运行 遇到了一个我在过去几个小时内无法解决的问题。
UI 由带有 Navbar 等的 Window 和用于显示当前 UserControl 的大 Frame/Grid 组成。
单击主窗口导航栏中的按钮会触发一个事件,然后只需使用以下几行即可毫无问题地切换 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),但至少它简单且有效。
问题是,我只能通过主窗口 Class 切换用户控件。但我希望能够从其中一个 UserControl 中切换 UserControl。 (例如,我的一个 UserControl 显示了一个数据网格,其中包含来自我的一个数据库 table 的所有数据。通过双击这些行之一,我希望能够将当前的 UserControl 切换为 table到另一个。)
但我真的不知道我该怎么做。我做了一些研究,但只找到了由许多不同的 类 和许多不同的事件处理程序等组成的解决方案,不幸的是我无法真正弄清楚该实现是如何工作的。并且它也被限制为 2 个 UserControls。
有什么方法可以在合理的时间内实现吗?我读过使用路由事件可以做到吗?因为我是 C# 的新手,所以我对事件、调度程序等完全陌生,因此很难处理所有基于事件的内容。 :D
谢谢 :)
一个简单的解决方案是使用数据绑定:
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
以可视化模型数据。
我目前正在 Visual Studio 中使用 WPF 开发一个应用程序作为 MySQL 数据库的前端,然后应该在学校中使用它来组织硬件等.更容易一点。 我是 C# 和 WPF 的新手,因此现在 运行 遇到了一个我在过去几个小时内无法解决的问题。 UI 由带有 Navbar 等的 Window 和用于显示当前 UserControl 的大 Frame/Grid 组成。
单击主窗口导航栏中的按钮会触发一个事件,然后只需使用以下几行即可毫无问题地切换 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),但至少它简单且有效。
问题是,我只能通过主窗口 Class 切换用户控件。但我希望能够从其中一个 UserControl 中切换 UserControl。 (例如,我的一个 UserControl 显示了一个数据网格,其中包含来自我的一个数据库 table 的所有数据。通过双击这些行之一,我希望能够将当前的 UserControl 切换为 table到另一个。)
但我真的不知道我该怎么做。我做了一些研究,但只找到了由许多不同的 类 和许多不同的事件处理程序等组成的解决方案,不幸的是我无法真正弄清楚该实现是如何工作的。并且它也被限制为 2 个 UserControls。
有什么方法可以在合理的时间内实现吗?我读过使用路由事件可以做到吗?因为我是 C# 的新手,所以我对事件、调度程序等完全陌生,因此很难处理所有基于事件的内容。 :D
谢谢 :)
一个简单的解决方案是使用数据绑定:
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
以可视化模型数据。