添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
原文: C# WPF 左侧菜单右侧内容布局效果实现

我们要做的效果是这样的,左侧是可折叠的菜单栏,右侧是内容区域,点击左侧的菜单项右侧内容区域则相应地切换。

wpf实现的话,我的办法是用一个tabcontrol,修改tabcontrol的样式模板,首先将控件的TabStripPlacement设置为left使tabcontrol的item header部分靠左内容靠右,然后用一个Expander将TabPanel包住实现可折叠菜单效果,最后就是把用到的控件样式修改一下即可。

先看下效果图:

WPF做出来的效果图:

未完善的问题:

不能添加多个可折叠菜单,我暂时没想到比较好的办法。

新建一个项目,名字随你,新建一个 自定义用户控件 前台修改为:

<TabControl x:Class="cloundmusic_left.controls.itabcontrol"
             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:local="clr-namespace:cloundmusic_left.controls"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <TabControl.Resources>
        <!--折叠菜单的箭头按钮-->
        <ControlTemplate x:Key="ExpanderToggleButton"
                 TargetType="{x:Type ToggleButton}">
            <Border Background="{TemplateBinding Background}" Width="{TemplateBinding Width}" x:Name="Border"
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CheckStates">
                        <VisualState x:Name="Checked">
                            <Storyboard>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                           Storyboard.TargetName="CollapsedArrow">
                                    <DiscreteObjectKeyFrame KeyTime="0"
                                      Value="{x:Static Visibility.Hidden}" />
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                           Storyboard.TargetName="ExpandededArrow">
                                    <DiscreteObjectKeyFrame KeyTime="0"
                                      Value="{x:Static Visibility.Visible}" />
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Unchecked" />
                        <VisualState x:Name="Indeterminate" />
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Grid Margin="0,0,13,0" HorizontalAlignment="Right" VerticalAlignment="Center">
                    <Path x:Name="CollapsedArrow"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Data="M 0 0 L 4 4 L 8 0 Z">
                        <Path.Fill>
                            <SolidColorBrush Color="#7d7d7d" />
                        </Path.Fill>
                    </Path>
                    <Path x:Name="ExpandededArrow"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Visibility="Collapsed"
            Data="M 0 4 L 4 0 L 8 4 Z">
                        <Path.Fill>
                            <SolidColorBrush Color="#7d7d7d" />
                        </Path.Fill>
                    </Path>
                </Grid>
            </Border>
        </ControlTemplate>
        <Style TargetType="{x:Type Expander}">
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="Foreground" Value="#7d7d7d"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Expander}">
                        <Border BorderBrush="#e1e1e2" BorderThickness="0,0,1,0">
                            <Grid Background="#f5f5f7">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition x:Name="ContentRow"
                           Height="0" />
                                </Grid.RowDefinitions>
                                <Border MinHeight="32" x:Name="Border"
                  Grid.Row="0"
                                    <Grid VerticalAlignment="Center">
                                        <ContentPresenter 
                                Margin="4"
                                ContentSource="Header"
                                RecognizesAccessKey="True" />
                                        <ToggleButton Background="Transparent" Width="{Binding ElementName=Border,Path=ActualWidth}" Panel.ZIndex="1" OverridesDefaultStyle="True"
                            Template="{StaticResource ExpanderToggleButton}"
                            IsChecked="{Binding IsExpanded, Mode=TwoWay, 
                  RelativeSource={RelativeSource TemplatedParent}}">
                                        </ToggleButton>
                                    </Grid>
                                </Border>
                                <Border x:Name="Content"
                  Grid.Row="1"
                                    <ContentPresenter/>
                                </Border>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsExpanded"
                   Value="True">
                                <Setter TargetName="ContentRow"
                    Property="Height"
                    Value="{Binding DesiredHeight, ElementName=Content}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="OverridesDefaultStyle" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid SnapsToDevicePixels="true">
                            <Border Cursor="Hand" MinWidth="199" MinHeight="32" x:Name="Bd" CornerRadius="0" Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="3,0,0,0" Padding="0" Margin="0">
                                <Grid VerticalAlignment="Center" HorizontalAlignment="Left">
                                    <StackPanel Orientation="Horizontal">
                                        <ContentPresenter x:Name="Content" Margin="17,0,0,0" ContentSource="Header" HorizontalAlignment="Left" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
                                    </StackPanel>
                                </Grid>
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="false">
                                <Setter Property="Foreground" Value="#5c5c5c"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="Foreground" Value="#000000"/>
                            </Trigger>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter Property="Panel.ZIndex" Value="1"/>
                                <Setter Property="Background" TargetName="Bd" Value="#e6e7ea"/>
                                <Setter Property="Foreground" Value="#000000"/>
                                <Setter Property="BorderThickness" TargetName="Bd" Value="3,0,0,0"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="#c62f2f"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TabControl.Resources>
    <TabControl.Style>
        <Style  TargetType="{x:Type TabControl}">
            <Setter Property="OverridesDefaultStyle"
          Value="True" />
            <Setter Property="TabStripPlacement"
          Value="Left" />
            <Setter Property="SnapsToDevicePixels"
          Value="True" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:itabcontrol}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="200" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <!--可折叠菜单-->
                            <Expander Header="{TemplateBinding iTitle}" Grid.Column="0">
                                <!--菜单项-->
                                <TabPanel x:Name="HeaderPanel"
                    IsItemsHost="True"
                    KeyboardNavigation.TabIndex="1"
                    Background="Transparent" />
                            </Expander>
                            <!--右侧内容区域-->
                            <Border x:Name="Border"
                  Grid.Column="1"
                  KeyboardNavigation.TabNavigation="Local"
                  KeyboardNavigation.DirectionalNavigation="Contained"
                  KeyboardNavigation.TabIndex="2">
                                <ContentPresenter x:Name="PART_SelectedContentHost"
                              Margin="4"
                              ContentSource="SelectedContent" />
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TabControl.Style>
</TabControl>

修改后你的vs也许会抱一个错:

这个报错就像vs错误列表里的警告一样,没啥卵用,不用理它,程序是可以运行的

ok继续,后台代码加一个依赖属性:

 public string iTitle
            get { return (string)GetValue(iTitleProperty); }
            set { SetValue(iTitleProperty, value); }
        public static readonly DependencyProperty iTitleProperty =
            DependencyProperty.Register("iTitle", typeof(string), typeof(itabcontrol));

然后只要在界面中使用这个控件即可。

呃我发现这个项目并没有什么难点,实现方法开头也说了,所以这里不一步步讲了。

值得一提的是,加入的Expander也就是可折叠菜单的header代表菜单名,这里我是把修改的这个TabControl写在一个自定义控件里的,在界面调用的时候默认是无法给它设置内容的,所以我们要在这个自定义控件中加入一个依赖属性,然后在样式中绑定这个属性。这里就涉及到一个比较有意思的东西,在样式中绑定一个属性也许你没接触过,但是你一定知道Binding的用法,而在样式中是没办法这么用的,那该怎么去做呢?相信你看完代码就知道了。

项目下载:

WPF实现强大的动态公式计算
数据库可以定义表不同列之间的计算公式,进行自动公式计算,但如何实现行上的动态公式计算呢?行由于可以动态扩展,在某些应用场景下将能很好的解决实际问题。本文就探讨一下如何在WPF中实现一种基于行字段的动态公式计算。
C# WPF上位机实现和下位机TCP通讯下位机使用北京大华程控电源DH1766-1,上位机使用WPF。实现了电压电流实时采集,曲线显示。上午在公司调试成功,手头没有程控电源,使用TCP服务端模拟。昨天写的TCP服务端正好排上用场。
原文:WPF 实现 DataGrid/ListView 分页控件 在WPF中,通常会选用DataGrid/ListView进行数据展示,如果数据量不多,可以直接一个页面显示出来。如果数据量很大,2000条数据,一次性显示在一个页面中,不仅消耗资源,而且用户体验也很糟糕。
WPF/UWP 的 Grid 布局竟然有 Bug,还不止一个!了解 Grid 中那些未定义的布局规则
原文:WPF/UWP 的 Grid 布局竟然有 Bug,还不止一个!了解 Grid 中那些未定义的布局规则 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
原文:WPF编游戏系列 之一 布局设计        本系列主要使用WPF和C#编写一个简单的小游戏(暂命名XMarket),意在通过该实例进一步学习和体验WPF,也欢迎广大同仁拍砖交流。言归正传,在编写一个软件前首先要思考软件的结构与布局,图片放在哪,按钮放在哪,都要先设计一下。
[-] .\Navicat-Cracker NavicatCrackerDlg.cpp:332 -3All patch solutions are suppressed. Patch abort!HI