WPF控件模板2

这篇具有很好参考价值的文章主要介绍了WPF控件模板2。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在控件模板和为其提供支持的代码之间有一个隐含约定。如果使用自定义控件模板替代控件的标准模板,就需要确保新模板能够满足控件的实现代码的所有需要。

在简单控件中,这个过程就比较容易,因为对模板几乎没有(或者完全没有)什么真正的要求。对于复杂控件,问题就显得有些微妙了,因为控件的外观和实现不可能是完全相互独立的。对于这种情况,控件需要对其可视化显示做出一些假设,而不管曾经被设计得多么好。

在前面已经看到了控件模板的这种需求的两个例子,占位元素(如ContentPresenter和ItemsPresenter)和模板绑定。为成功地创建控件模板,需要仔细查看相关控件的标准模板,并注意分析这些技术的用法,然后将它们应用到自己的模板中。

嵌套的模板

按钮控件的模板可分解成几个较简单的部分。然而,许多模板并非如此简单。在某些情况下,控件模板将包含每个自定义模板也需要的大量元素。而在有些情况下,改变控件的外观涉及创建多个模板。

例如,假设计划修改熟悉的ListBox控件。创建这个示例的第一部是为ListBox控件设计模板,并酌情添加自动应用模板的样式。

    <Style TargetType="{x:Type ListBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <Border Name="Border" Background="{StaticResource ListBoxBackgroundBrush}" BorderBrush="{StaticResource StandardBorderBrush}" BorderThickness="1" CornerRadius="3">
                        <ScrollViewer Focusable="False">
                            <ItemsPresenter Margin="2"></ItemsPresenter>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

该样式使用两个画刷绘制边框和背景。实际模板是标准模板ListBox的简化版本。在Border元素内部是为列表提供滚动功能的 ScrollViewer 元素以及容纳所有列表项的 ItemsPresenter 元素。

对于该模板,最值得注意之处是它未提供的功能——配置列表中各项的外观。没有改功能,被选择的元素总是使用熟悉的蓝色背景突出显示。为改变这种行为,需要为ListBoxItem控件添加控件模板,ListBoxItem 控件时封装列表中每个单独元素内容的内容控件。

与ListBox模板一样,可使用元素类型样式应用ListBoxItem模板。下面的基本模板在一个不可见的边框中封装了每个项。因为ListBoxItem是内容控件,所以需要使用ContentPresenter 元素在其内部放置项的内容。除这些基本内容外,还有当鼠标移动到项上或单击时做出响应的触发器:

    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border Name="Border" BorderThickness="2" CornerRadius="3" Padding="1" SnapsToDevicePixels="True">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <EventTrigger RoutedEvent="ListBoxItem.MouseEnter">
                            <EventTrigger.Actions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="FontSize" To="20" Duration="0:0:1"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger.Actions>
                        </EventTrigger>
                        <EventTrigger RoutedEvent="ListBoxItem.MouseLeave">
                            <EventTrigger.Actions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="FontSize" BeginTime="0:0:0.5" Duration="0:0:0.2"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger.Actions>
                        </EventTrigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource HoverBorderBrush}"/>
                        </Trigger>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
                            <Setter TargetName="Border" Property="TextBlock.Foreground" Value="{StaticResource SelectedForegroundBrush}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

总之,可以使用这两个模板创建当鼠标移动到当前定位的项上时使用动画放大项的列表框。因为每个ListBoxItem可具有自己的动画,所以当用户在列表框中上下移动鼠标时,将看到几个项开始增大,然后再次收缩。需要注意,缩小动画省略了From和To属性,通过这种方式,缩小动画总将文本从当前尺寸缩小到它原来的尺寸。

修改滚动条

列表框还有一个方面没有改变:右边的滚动条。它是ScrollViewer 元素的一部分,ScrollViewer元素是ListBox模板的一部分。尽管这里重新定义了ListBox模板,但没有替换ScrollBar的ScrollViewer。

为自定义该细节,可为ListBox控件创建一个新的ScrollViewer模板,然后可将 ScrollViewer模板指向自定义的ScrollBar模板。然而 ,还有更简单的选择。可创建一个改变所有ScrollBar控件模板的特性于元素类型的样式。这样就避免了创建ScrollViewer模板所需的额外工作。

当然,还需要考虑这种设计会对应用程序的其他部分造成什么影响。如果创建元素类型样式ScrollBar,并将其添加到窗口的Resources集合中,对于窗口的所有控件,无论何时使用ScrollBar控件,都会具有新样式的滚动条,这可能正是您所希望的效果。另一方面,如果希望只改变ListBox控件中的滚动条,就必须为ListBox控件本身的资源集合添加元素类型样式 ScrollBar。最后,如果希望改变整个应用程序中所有滚动条的外观,可将该样式添加到 App.xaml文件的资源集合中。

ScrollBar控件出奇复杂,它实际上是一个由更小部分组成的集合。

滚动条的背景有Track类表示——实际上是一个具有阴影并且被拉伸沾满整个滚动条长度的矩形。滚动条的末尾处是按钮,通过这些按钮可以向上或向下(或向左或向右)滚动一个步长。这些按钮时RepeatButton类的实例,该类继承自ButtonBase类。RepeatButton类和普通Button类之间的重要区别在于,如果在RepeatButton按钮上保持鼠标为按下状态,就会反复触发Click事件(对于滚动条这是非常方便的)。

在滚动条的中间是代表当前滚动内容中当前位置的Thumb元素。并且最有趣的是,滑块两侧的空白实际上由另外两个RepeatButton 对象构成,它们是透明的。当单击这两个按钮中的一个时,滚动条会滚动一整页(一页是滚动内容所在的可见窗口中的内容量)。通过单击滑块两侧的条形区域,可快速浏览滚动内容,这一功能是大家所熟悉的。

下面是用于垂直滚动条的模板:

    <ControlTemplate x:Key="VerticalScrollBar" TargetType="{x:Type ScrollBar}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="18"/>
                <RowDefinition Height="*"/>
                <RowDefinition MaxHeight="18"/>
            </Grid.RowDefinitions>
            <RepeatButton Grid.Row="0" Height="18" Style="{StaticResource ScrollBarLineButtonStyle}" Command="ScrollBar.LineUpCommand" >
                <Path Fill="{StaticResource GlyphBrush}" Data="M 0 4 L 8 4 L 4 0 Z"></Path>
            </RepeatButton>
            <Track Name="PART_Track" Grid.Row="1" IsDirectionReversed="True" ViewportSize="0">
                <Track.DecreaseRepeatButton>
                    <RepeatButton Command="ScrollBar.PageUpCommand" Style="{StaticResource ScrollBarPageButtonStyle}"></RepeatButton>
                </Track.DecreaseRepeatButton>
                <Track.Thumb>
                    <Thumb Style="{StaticResource ScrollBarThumbStyle}"></Thumb>
                </Track.Thumb>
                <Track.IncreaseRepeatButton>
                    <RepeatButton Command="ScrollBar.PageDownCommand" Style="{StaticResource ScrollBarPageButtonStyle}"></RepeatButton>
                </Track.IncreaseRepeatButton>
            </Track>
            <RepeatButton Grid.Row="3" Height="18" Style="{StaticResource ScrollBarLineButtonStyle}" Command="ScrollBar.LineDownCommand">
                <Path Fill="{StaticResource GlyphBrush}" Data="M 0 0 L 4 4 L 8 0 Z"></Path>
            </RepeatButton>
        </Grid>
    </ControlTemplate>

一旦理解滚动条的多部分结构,上面的模板就非常直观了。下面列出需要注意的几个要点:

1、垂直滚动条由一个包含三行的网格构成。顶行和底行容纳两端的按钮(并显示为箭头)。它们固定占用18个单位。中间部分容纳Track元素,占用了剩余空间。

2、两端的RepeatButton元素使用相同的样式。唯一的区别是Content属性,该属性包含了一个用于绘制箭头的Path对象,因为顶部具有上箭头而底部的按钮具有下箭头。为简明起见,这些箭头使用微语言路径。其他细节(如背景填充和箭头周围显示的圆圈)是在控件模板中定义的。

3、两个按钮都链接到ScrollBar类的命令(LineUpCommand 和 LineDownCommand)。这正是其工作原理。只要提供链接到这个命令的按钮即可,不必考虑按钮的名称是什么,也不必考虑其外观像什么或使用哪个特定的类。

4、Track元素名为PART_Track。为使ScrollBar类能够成功的关联到它的代码,必须使用这个名称。如果查看ScrollBar类的默认模板(类似上面的模板,但更长一些),也会看到该元素。

5、Track.ViewportSize 属性被设置为0,。这是该模板特有的实现细节,可确保Thumb元素总有相同的尺寸(通常,滑块根据内容按比例地改变尺寸,因此如果滚动的内容在窗口中基本上能够显示,这是滑块会变得较长)。

6、Track元素封装了两个RepeatButton对象和Thumb元素。同样,这些按钮通过命令连接到适当的功能。

这里模板使用了键名,明确指定将它作为垂直滚动条,可确保它不能被自动应用,即使同时设置了TargetType属性。这里使用这种方法的原因是,该模板只适用于垂直方向的滚动条。而且,如果ScrollBar.Orientation属性设置为Vertical,元素类型样式会使用触发器自动应用控件模板:

    <Style TargetType="{x:Type ScrollBar}">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Style.Triggers>
            <Trigger Property="Orientation" Value="Vertical">
                <Setter Property="Width" Value="18"/>
                <Setter Property="Height" Value="Auto" />
                <Setter Property="Template" Value="{StaticResource VerticalScrollBar}" />
            </Trigger>
        </Style.Triggers>
    </Style>

尽管可以使用相同的基本部分很容易地创建水平滚动条,但这里没有采取该步骤,从而保留了正常样式的水平滚动条。

最后一项任务是填充格式化各个RepeatButton对象和Thumb元素的样式。这些样式比较简单,但它们确实改变了滚动条的标准外观。

    <Style x:Key="ScrollBarLineButtonStyle" TargetType="{x:Type RepeatButton}">
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Grid Margin="1">
                        <Ellipse Name="Border" StrokeThickness="1" Stroke="{StaticResource StandardBorderBrush}" Fill="{StaticResource StandardBrush}"></Ellipse>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter TargetName="Border" Property="Fill" Value="{StaticResource PressedBrush}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ScrollBarPageButtonStyle" TargetType="{x:Type RepeatButton}">
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Border Background="Transparent" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ScrollBarThumbStyle" TargetType="{x:Type Thumb}">
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Margin" Value="1,0,1,0" />
        <Setter Property="Background" Value="{StaticResource StandardBrush}" />
        <Setter Property="BorderBrush" Value="{StaticResource StandardBorderBrush}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Thumb}">
                    <Ellipse Stroke="{StaticResource StandardBorderBrush}" Fill="{StaticResource StandardBrush}"></Ellipse>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

与正常滚动条不同,在该模板中没有为Track元素指定背景,所以保持原来的透明背景。这样,列表框的轻微阴影渐变可透过滚动条显示。

至此,ListBox自定义模板就完成了,这里定义的ScrollBar样式会自动应用于ListBox模板中的ScrollViewer上。

代码清单:

Resources/Brush.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="StandardBorderBrush" Color="#888" />
    <SolidColorBrush x:Key="StandardBackgroundBrush" Color="#FFF" />
    <SolidColorBrush x:Key="HoverBorderBrush" Color="#DDD" />
    <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="Gray" />
    <SolidColorBrush x:Key="SelectedForegroundBrush" Color="White" />
    <LinearGradientBrush x:Key="ListBoxBackgroundBrush" StartPoint="0,0" EndPoint="1,0.001">
        <GradientBrush.GradientStops>
            <GradientStopCollection>
                <GradientStop Color="White" Offset="0.0" />
                <GradientStop Color="White" Offset="0.6" />
                <GradientStop Color="#DDDDDD" Offset="1.2"/>
            </GradientStopCollection>
        </GradientBrush.GradientStops>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="StandardBrush" StartPoint="0,0" EndPoint="0,1">
        <GradientBrush.GradientStops>
            <GradientStopCollection>
                <GradientStop Color="#FFF" Offset="0.0"/>
                <GradientStop Color="#CCC" Offset="1.0"/>
            </GradientStopCollection>
        </GradientBrush.GradientStops>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="GlyphBrush" Color="#444" />
    <LinearGradientBrush x:Key="PressedBrush" StartPoint="0,0" EndPoint="0,1">
        <GradientBrush.GradientStops>
            <GradientStopCollection>
                <GradientStop Color="#BBB" Offset="0.0"/>
                <GradientStop Color="#EEE" Offset="0.1"/>
                <GradientStop Color="#EEE" Offset="0.9"/>
                <GradientStop Color="#FFF" Offset="1.0"/>
            </GradientStopCollection>
        </GradientBrush.GradientStops>
    </LinearGradientBrush>
</ResourceDictionary>

Resources/ScrollBar.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Brush.xaml"></ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>

    <Style x:Key="ScrollBarLineButtonStyle" TargetType="{x:Type RepeatButton}">
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Grid Margin="1">
                        <Ellipse Name="Border" StrokeThickness="1" Stroke="{StaticResource StandardBorderBrush}" Fill="{StaticResource StandardBrush}"></Ellipse>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter TargetName="Border" Property="Fill" Value="{StaticResource PressedBrush}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ScrollBarPageButtonStyle" TargetType="{x:Type RepeatButton}">
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Border Background="Transparent" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ScrollBarThumbStyle" TargetType="{x:Type Thumb}">
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Margin" Value="1,0,1,0" />
        <Setter Property="Background" Value="{StaticResource StandardBrush}" />
        <Setter Property="BorderBrush" Value="{StaticResource StandardBorderBrush}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Thumb}">
                    <Ellipse Stroke="{StaticResource StandardBorderBrush}" Fill="{StaticResource StandardBrush}"></Ellipse>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <ControlTemplate x:Key="VerticalScrollBar" TargetType="{x:Type ScrollBar}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="18"/>
                <RowDefinition Height="*"/>
                <RowDefinition MaxHeight="18"/>
            </Grid.RowDefinitions>
            <RepeatButton Grid.Row="0" Height="18" Style="{StaticResource ScrollBarLineButtonStyle}" Command="ScrollBar.LineUpCommand" >
                <Path Fill="{StaticResource GlyphBrush}" Data="M 0 4 L 8 4 L 4 0 Z"></Path>
            </RepeatButton>
            <Track Name="PART_Track" Grid.Row="1" IsDirectionReversed="True" ViewportSize="0">
                <Track.DecreaseRepeatButton>
                    <RepeatButton Command="ScrollBar.PageUpCommand" Style="{StaticResource ScrollBarPageButtonStyle}"></RepeatButton>
                </Track.DecreaseRepeatButton>
                <Track.Thumb>
                    <Thumb Style="{StaticResource ScrollBarThumbStyle}"></Thumb>
                </Track.Thumb>
                <Track.IncreaseRepeatButton>
                    <RepeatButton Command="ScrollBar.PageDownCommand" Style="{StaticResource ScrollBarPageButtonStyle}"></RepeatButton>
                </Track.IncreaseRepeatButton>
            </Track>
            <RepeatButton Grid.Row="3" Height="18" Style="{StaticResource ScrollBarLineButtonStyle}" Command="ScrollBar.LineDownCommand">
                <Path Fill="{StaticResource GlyphBrush}" Data="M 0 0 L 4 4 L 8 0 Z"></Path>
            </RepeatButton>
        </Grid>
    </ControlTemplate>
    <Style TargetType="{x:Type ScrollBar}">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Style.Triggers>
            <Trigger Property="Orientation" Value="Vertical">
                <Setter Property="Width" Value="18"/>
                <Setter Property="Height" Value="Auto" />
                <Setter Property="Template" Value="{StaticResource VerticalScrollBar}" />
            </Trigger>
        </Style.Triggers>
    </Style>
</ResourceDictionary>

Resources/ListBox.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Brush.xaml"></ResourceDictionary>
        <ResourceDictionary Source="ScrollBar.xaml"></ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
    <Style TargetType="{x:Type ListBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <Border Name="Border" Background="{StaticResource ListBoxBackgroundBrush}" BorderBrush="{StaticResource StandardBorderBrush}" BorderThickness="1" CornerRadius="3">
                        <ScrollViewer Focusable="False">
                            <ItemsPresenter Margin="2"></ItemsPresenter>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border Name="Border" BorderThickness="2" CornerRadius="3" Padding="1" SnapsToDevicePixels="True">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <EventTrigger RoutedEvent="ListBoxItem.MouseEnter">
                            <EventTrigger.Actions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="FontSize" To="20" Duration="0:0:1"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger.Actions>
                        </EventTrigger>
                        <EventTrigger RoutedEvent="ListBoxItem.MouseLeave">
                            <EventTrigger.Actions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="FontSize" BeginTime="0:0:0.5" Duration="0:0:0.2"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger.Actions>
                        </EventTrigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource HoverBorderBrush}"/>
                        </Trigger>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
                            <Setter TargetName="Border" Property="TextBlock.Foreground" Value="{StaticResource SelectedForegroundBrush}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

MainWindow.xaml

<Window x:Class="TestControlTemplate2.MainWindow"
        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:TestControlTemplate2"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/ListBox.xaml"></ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <ListBox Margin="5" ScrollViewer.CanContentScroll="False">
            <ListBoxItem>One</ListBoxItem>
            <ListBoxItem>Two</ListBoxItem>
            <ListBoxItem>Three</ListBoxItem>
            <ListBoxItem>Four</ListBoxItem>
            <ListBoxItem>Five</ListBoxItem>
            <ListBoxItem>Six</ListBoxItem>
            <ListBoxItem>Seven</ListBoxItem>
            <ListBoxItem>EightEight</ListBoxItem>
            <ListBoxItem>NineNineNine</ListBoxItem>
            <ListBoxItem>TenTenTenTen</ListBoxItem>
            <ListBoxItem>ElevenElevenElevenEleven</ListBoxItem>
            <ListBoxItem>TwelveTwelveTwelveTwelveTwelve</ListBoxItem>
        </ListBox>
    </Grid>
</Window>

MainWindow.xaml.cs文章来源地址https://www.toymoban.com/news/detail-731856.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TestControlTemplate2;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

到了这里,关于WPF控件模板2的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 程序人生,中秋共享

    在这个中秋节即将来临之际,作为一名程序员,对这个传统佳节有着特殊的感悟。程序人生,就像这中秋的明月一样,有时圆满,有时缺憾,但只要我们用心去感受,去体验,就能找到那份属于自己的精彩。中秋节,是一个团圆的日子。在这个特殊的日子里,我们不仅与家人

    2024年02月07日
    浏览(57)
  • 《程序人生》

    《程序人生》对乔布斯和马斯克访谈的反思: 1、这个世界不在乎你的自尊,只在乎你自我感觉良好的同时有所成就。说明大多数人的观点是《乌合之众》,必须有从想到去做到的能力,面子是无能者维护尊严的盾牌。 2、年轻时候一定要大量阅读,因为年轻时候有很多梦想,

    2024年02月02日
    浏览(58)
  • 【如何重燃程序人生】

    以下是一些可以重燃程序人生的建议: 1.学习新技术:尝试学习新的技术或框架,掌握新的语言或工具可以帮助您挑战自己并保持激情。 参加活动:参加一些技术会议、讲座、研讨会或者社区活动,可以与其他程序员交流思想和学习最新进展。 开始一个新项目:尝试开始一

    2024年02月11日
    浏览(52)
  • 程序人生(CSAPP大作业)

    摘  要 本文介绍了 Hello 程序的生命周期。本文通过对Hello在Linux下的预处理、编译、汇编、链接等进程的分析,详细讲解了一个程序从诞生到执行再到消亡的典型过程。虽然程序执行的过程在程序员眼中只是屏幕上显示的一根字符串,但在短短的几毫秒内,程序经历了预处理

    2023年04月24日
    浏览(58)
  • 雷军:我的程序人生路

    今天有朋友发给我一篇我在20年前在BBS上写的帖子。那还是1996年,我们通过电话线拨号连接到西点BBS上飙帖子玩的年代。那是一个互联网混沌初开的年代,那是一个BBS和Email几乎主宰了全部互联网的年代,那是一个青春的理想和热血沸腾的年代。 我是一个程序员,一个软件工

    2024年02月04日
    浏览(82)
  • 哈工大CSAPP程序人生大作业

    正在上传…重新上传取消 计算机系统 大作业 题     目   程序人生 -Hello’s P2P  专       业    计算机科学与技术        学    号   2021110991             班    级      2103101             学       生         安心           指 导 教 师    

    2023年04月24日
    浏览(72)
  • 程序人生——Java数组和集合使用建议(2)

    程序人生——Java数组和集合使用建议(2) 需求:要删除一个ArrayList中的20-30范围内的元素;将原列表转换为一个可变列表,然后使用subList获取到原列表20到30范围内的一个视图(View),然后清空该视图内的元素,即可在原列表中删除20到30范围内的元素 建议72:生成子列表后

    2024年03月19日
    浏览(50)
  • 【程序人生】上海城市开发者社区小聚有感

    📫作者简介: 小明java问道之路 , 2022年度博客之星全国TOP3 ,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化,文章内容兼具广度、深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公司后端高级工程师。          📫 热衷分享,喜欢原

    2024年02月06日
    浏览(68)
  • 程序人生 | 编程的上帝视角应该怎么去找

      前言 📫 作者简介 :小明java问道之路,专注于Linux内核/汇编/HotSpot/C++/Java/源码/架构/算法 就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计📫  🏆 CSDN专家博主/Java优质创作者/CSDN内容合伙人 、InfoQ签约作者 、阿里云专家/签约博主、

    2023年04月24日
    浏览(89)
  • 【程序人生】如何在工作中保持稳定的情绪?

    在工作中保持稳定的情绪是现代生活中一个备受关注的话题。随着职场压力和工作挑战的增加,我们常常发现自己情绪波动不定,甚至受到负面情绪的困扰。然而,保持稳定的情绪对于我们的工作效率、人际关系和整体幸福感都至关重要。 无论你是一位职场新人还是一位资深

    2024年02月15日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包