You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Visual Basic WPF中实现多窗口共用导航栏可复用组件

解决方案

完全可以通过WPF的用户控件(UserControl) 实现导航栏的复用,将导航栏的UI和业务逻辑封装为独立组件后,所有窗口均可直接引用,无需重复复制代码,具体实现步骤如下:

步骤1:创建导航栏用户控件

右键你的WPF项目 -> 选择【添加】->【新建项】-> 选中【用户控件(WPF)】,命名为NavbarControl.xaml,点击确定后会自动生成对应的XAML布局文件和VB后台类文件。

步骤2:迁移导航栏XAML布局

将你现有代码中navGrid的完整内容复制到NavbarControl.xaml中,最终NavbarControl.xaml代码如下:

<UserControl x:Class="RestaurantManager.NavbarControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:fa5="http://schemas.fontawesome.com/icons/"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="70">
    <Grid x:Name="navGrid" Background="#212121">
        <Grid.RowDefinitions>
            <RowDefinition Height="70"/>
            <RowDefinition Height="70"/>
            <RowDefinition Height="70"/>
            <RowDefinition Height="70"/>
        </Grid.RowDefinitions>
        <!-- 菜单项定义 -->
        <Border Grid.Row="0" BorderBrush="White" BorderThickness="0 0 0 .1"/>
        <Button x:Name="logoBtn" Grid.Row="0" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
        <TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="40" Foreground="#03DAC5">
            E
        </TextBlock>
        <Border Grid.Row="1" BorderBrush="White" BorderThickness="0 0 0 .1"/>
        <Button x:Name="floorBtn" Grid.Row="1" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
        <StackPanel x:Name="floorStack" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
            <fa5:SvgAwesome Icon="Solid_BorderAll" Width="20" Foreground="White"/>
            <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Floor</TextBlock>
        </StackPanel>
        <Border Grid.Row="2" BorderBrush="White" BorderThickness="0 0 0 .1"/>
        <Button x:Name="clientsBtn" Grid.Row="2" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
        <StackPanel x:Name="clientsStack" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Opacity=".1">
            <fa5:SvgAwesome Icon="Solid_UserFriends" Width="20" Foreground="White"/>
            <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Clients</TextBlock>
        </StackPanel>
        <Border Grid.Row="3" BorderBrush="White" BorderThickness="0 0 0 .1"/>
        <Button x:Name="settingsBtn" Grid.Row="3" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
        <StackPanel x:Name="settingsStack" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Center" Opacity=".1">
            <fa5:SvgAwesome Icon="Solid_Cogs" Width="20" Foreground="White"/>
            <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Settings</TextBlock>
        </StackPanel>
    </Grid>
</UserControl>

步骤3:迁移导航栏逻辑到用户控件后台

将原窗口中的导航交互逻辑复制到NavbarControl.xaml.vb中,为了适配多窗口复用,建议新增路由事件通知父窗口导航项被点击:

Imports System.Windows.RoutedEventArgs

Partial Public Class NavbarControl
    ' 自定义导航点击路由事件,父窗口可以监听该事件处理跳转逻辑
    Public Shared ReadOnly NavItemClickedEvent As RoutedEvent = EventManager.RegisterRoutedEvent(
        "NavItemClicked", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(NavbarControl))

    Public Event NavItemClicked As RoutedEventHandler

    Private Sub SetAllInactive()
        For Each child In navGrid.Children
            If TypeOf child Is StackPanel Then
                child.Opacity = 0.1
            End If
        Next
    End Sub

    Private Sub LogoBtnClick(sender As Object, e As RoutedEventArgs) Handles logoBtn.Click
        SetAllInactive()
        floorStack.Opacity = 1
        RaiseEvent NavItemClicked(Me, New RoutedEventArgs With {.Source = "Logo"})
    End Sub

    Private Sub FloorBtnClick(sender As Object, e As RoutedEventArgs) Handles floorBtn.Click
        SetAllInactive()
        floorStack.Opacity = 1
        RaiseEvent NavItemClicked(Me, New RoutedEventArgs With {.Source = "Floor"})
    End Sub

    Private Sub ClientsBtnClick(sender As Object, e As RoutedEventArgs) Handles clientsBtn.Click
        SetAllInactive()
        clientsStack.Opacity = 1
        RaiseEvent NavItemClicked(Me, New RoutedEventArgs With {.Source = "Clients"})
    End Sub

    Private Sub SettingsBtnClick(sender As Object, e As RoutedEventArgs) Handles settingsBtn.Click
        SetAllInactive()
        settingsStack.Opacity = 1
        RaiseEvent NavItemClicked(Me, New RoutedEventArgs With {.Source = "Settings"})
    End Sub
End Class

步骤4:在窗口中引用导航控件

修改你原来的窗口XAML代码,移除原有导航栏代码,引入封装好的NavbarControl即可,以你原有的FloorWindow为例:

<Window x:Class="FloorWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:RestaurantManager"
        mc:Ignorable="d"
        Title="Restaurant Floor" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="70"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <!-- 引用封装好的导航控件 -->
        <local:NavbarControl x:Name="MainNavbar" NavItemClicked="MainNavbar_NavItemClicked"/>
        <!-- 第二列放当前窗口的独有内容 -->
        <Grid Grid.Column="1">
            <!-- 此处写当前窗口的业务UI -->
        </Grid>
    </Grid>
</Window>

在窗口后台监听导航点击事件,处理对应跳转逻辑即可:

Private Sub MainNavbar_NavItemClicked(sender As Object, e As RoutedEventArgs)
    Dim navKey As String = e.Source.ToString()
    Select Case navKey
        Case "Floor"
            ' 处理Floor页跳转逻辑
        Case "Clients"
            ' 处理Clients页跳转逻辑
        Case "Settings"
            ' 处理Settings页跳转逻辑
    End Select
End Sub

优化建议

  • 原逻辑中通过字符串对比控件类型的写法可以替换为If TypeOf child Is StackPanel Then,运行更稳定,不会因为类名变动出现异常
  • 后续如果需要扩展导航项,只需要修改NavbarControl的代码,所有引用该控件的窗口都会自动同步更新

内容的提问来源于stack exchange,提问作者DeadSec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:24:04