3、怎样建立一个 WPF User Control 并在一个 WPF Application 中使用它 ( VB )

与WinForm不同,WPF没有类似的子窗口。使用第三方控件感觉有失认真学习WPF的本意。初步了解后想到使用UserControl控件。UserControl依赖项属性等内容一堆,本文介绍先建立XAML文件。

在XAML命名空间折腾多时,总是“在…中无 …(类)名称”。第2篇详细研究了MSDN的文件。终其关键就2点:

1) 在用户控件中所定义的类命名,自动映射到

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation";

2) 在应用文件中规定好 xmlns:local="clr-namespace:(根命名空间)"。

此外我所走的弯路是,先新建一个UserControl项目,再新建一个应用项目(如参考文献1),然后将UserControl项目添加到应用项目。这样的做法似有不当(可能得视为2个程序集去做,未尝试)弄到大半夜也不行。

闲话少说,直接给结果。(以下使用VB2013)

3.1 怎样建立一个 WPF User Control 并使用

第一步,规划好文件名、类名。新建应用项目。用规划的应用文件名保存。我的文件名是:MyALCIDEApp。

第二步,点开“项目-->属性”面板,程序集名称自动为MyALCIDEApp。修改根命名空间为MyALCIDEApp,如下图:

图1、设置:类命名根命名空间

 

 

 

 

 

 

 

 

 

 

 

第三布,编写应用程序的XAML文件,为UserControl预留位置。可先以一条语句代替:

<local:LeftBarNav></local:LeftBarNav>

此外,添加一个声明,声明类引用命名空间地址(本术语为私造):

xmlns:local="clr-namespace:MyALCIDEApp">

我的程序如下(最终代码)。此时,以上第一条语句提示错误,删除该条语句,界面窗口内运行正常。

MainWindow.XAML
<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:MyALCIDEApp">

    <!-- CSS -->
    <Window.Resources>
        <ControlTemplate x:Key="rect" TargetType="{x:Type CheckBox}">
            <StackPanel>
                <Rectangle Name="breakRectangle" Stroke="Red" StrokeThickness="2" Width="20" Height="20">
                    <Rectangle.Fill>
                        <SolidColorBrush Color="White"/>
                    </Rectangle.Fill>
                </Rectangle>
                <ContentPresenter Margin="10" />
            </StackPanel>
        </ControlTemplate>
    </Window.Resources>

    <!-- 停靠容器 -->
    <DockPanel LastChildFill="True">

        <!-- 1、菜单栏 -->
        <Menu DockPanel.Dock="Top" VerticalAlignment="top" Height="30" FontSize="14.667" Padding="3"
                Background="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" >
            <MenuItem Header="File" Background="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}">
                <MenuItem Header="New"></MenuItem>
                <MenuItem Header="Open"></MenuItem>
                <MenuItem Header="Save"></MenuItem>
                <Separator></Separator>
                <MenuItem Header="Exit"></MenuItem>
            </MenuItem>
            <MenuItem Header="Edit">
                <MenuItem Header="Undo"></MenuItem>
                <MenuItem Header="Redo"></MenuItem>
                <Separator></Separator>
                <MenuItem Header="Cut"></MenuItem>
                <MenuItem Header="Copy"></MenuItem>
                <MenuItem Header="Paste"></MenuItem>
            </MenuItem>
        </Menu>

        <!-- 2、工具栏 -->
        <ToolBar DockPanel.Dock="Top" Height="30" VerticalAlignment="Top" 
                    Background="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}">
            <ComboBox SelectedIndex="0">
                <ComboBoxItem>100%</ComboBoxItem>
                <ComboBoxItem>50%</ComboBoxItem>
                <ComboBoxItem>25%</ComboBoxItem>
            </ComboBox>
            <Button Content="save"></Button>
            <Button Content="saveall"></Button>
            <Separator></Separator>
            <CheckBox FontWeight="Bold">Bold</CheckBox>
            <CheckBox FontStyle="Italic">Italic</CheckBox>
            <CheckBox>
                <TextBlock TextDecorations="Underline">Underline</TextBlock>
            </CheckBox>
            <Separator></Separator>
        </ToolBar>

        <!-- 3、状态栏 -->
        <StatusBar Grid.Row="1" DockPanel.Dock="Bottom" 
                    Height="30" FontSize="14.667" Margin="0,0,3,3"
                    VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" 
                    Background="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" 
                    SnapsToDevicePixels="True" >
            <!-- 定义状态栏条目容器 -->
            <StatusBar.ItemsPanel>
                <!-- 定义Grid表格 -->
                <ItemsPanelTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
            </StatusBar.ItemsPanel>

            <!-- 状态 -->
            <TextBlock>Left Side</TextBlock>
            <StatusBarItem Grid.Column="1">
                <TextBlock>Right Side</TextBlock>
            </StatusBarItem>

        </StatusBar>

        <!-- 3、客户区 -->
        <DockPanel LastChildFill="True">
            <!-- User Controls -->
            <local:LeftBarNav></local:LeftBarNav>
            <!-- -->
            <Viewbox DockPanel.Dock="Right" HorizontalAlignment="Right" Width="160"/>
            <Button>客户区</Button>
        </DockPanel>


    </DockPanel>
</Window>
MainWindow.XAML

第四步,从“解决方案资源管理器”窗口,右键项目名称-->添加-->用户控件。在建立界面选择用户控件,输入规划好的文件名(我的文件名是LfetBarNav)。这样来建立用户控件。保存后,点开“项目-->属性”面板,可以看到程序集名称仍为MyALCIDEApp。根命名空间仍为MyALCIDEApp。这样用户控件与应用程序位于同一程序集。

第五步,编辑LfetBarNav.XAML。该用户控件类命名的语句其实只有一条:

x:Class="LeftBarNav"

代码如下:

LeftBarNav.XAML

<UserControl x:Class="LeftBarNav"
             
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Border
            Background="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}" >
        <StackPanel >
            <!-- 系统功能导航按钮************************************************* -->
            <Expander Margin="5" Padding="5" Header="系统功能">
                <Button Padding="3">系统功能</Button>
            </Expander>
            <!-- 输入接口导航按钮************************************************* -->
            <Expander Margin="5" Padding="5" Header="输入接口">
                <StackPanel>
                    <Button Padding="3">A0</Button>
                    <Button Padding="3">A1</Button>
                    <Button Padding="3">A2</Button>
                </StackPanel>
            </Expander>
            <!-- 输出接口导航按钮************************************************* -->
            <Expander Margin="5" Padding="5" Header="输出接口">
                <StackPanel>
                    <Button Padding="3">Ec1</Button>
                    <Button Padding="3">Ec2</Button>
                </StackPanel>
            </Expander>

            <!-- 逻辑控制导航按钮************************************************* -->
            <Expander Margin="5" Padding="5" Header="逻辑控制">
                <StackPanel>
                    <!-- 并列逻辑控制导航按钮 -->
                    <Expander Margin="5" Padding="5" Header="并列逻辑控制">
                        <StackPanel>
                            <Button Padding="3">EU31</Button>
                            <Button Padding="3">EU32</Button>
                            <Button Padding="3">EU33</Button>
                            <Button Padding="3">EU34</Button>
                        </StackPanel>
                    </Expander>
                    <!-- 串列逻辑控制导航按钮 -->
                    <Expander Margin="5" Padding="5" Header="串列逻辑控制">
                        <StackPanel>
                            <Button Padding="3">EU31</Button>
                            <Button Padding="3">EU32</Button>
                            <Button Padding="3">EU33</Button>
                            <Button Padding="3">EU34</Button>
                        </StackPanel>
                    </Expander>
                </StackPanel>
            </Expander>
        </StackPanel>
    </Border>
</UserControl>
LeftBarNav.XAML

第五步,选中LeftBarNav.XAML代码窗口,生成-->生成选定内容。编译成功后,点开应用程序代码窗口,错误提示消失,界面窗口运行正常。运行结果如下图。

运行界面

 

 

 

 

 

 

 

 

 

 

3.2 再谈User Control类命名空间以及在应用程序中引用

讲起来命名空间篇幅蛮多。其实根本原理就两条:1、在用户控件所命名的“类名”自动映射到微软的“类命名空间”,引用时是从微软的“类命名空间”引用。2、路径都是自动的,不用考虑。只要规定好根命名空间即可。这一根命名空间在项目属性中规定,在应用程序中声明。

语句就是三条(如下),MSDN介绍的一堆俱可不予考虑。

3.2.1 在User Control中命名“类命名”的语句:

x:Class="LeftBarNav"

在名称面前不能有根目录,例如:

x:Class="MyALCIDEApp.LeftBarNav"

这是不对的。参考文献1是这样写的,实际是错误的。MyALCIDEApp是在项目属性中规定的!!!

3.2.2 在应用程序中声明的语句:

xmlns:local="clr-namespace:MyALCIDEApp"

其它都是不对的,例如按照MSDN叙述,在后边加";A..."是不行的。MyALCIDEApp是在项目属性中规定好的,用其他一概不行。

3.2.3 在应用程序中使用User Control的语句:

<local:LeftBarNav></local:LeftBarNav>

类名称LeftBarNav前后也不能加任何东西,这名称是由User Control。

 

参考文献

附两篇文献。第2篇下面学习依赖项参考。

1

http://www.dotnetheaven.com/article/wpf-user-controls-wpf-in-vb.net

2

http://www.codeproject.com/Articles/32825/How-to-Creating-a-WPF-User-Control-using-it-in-a-W

 

posted @ 2015-10-16 11:01  moiska  阅读(483)  评论(0编辑  收藏  举报